diff --git a/admin-portal/README.adoc b/admin-portal/README.adoc index bcaea3d35e2de3b2338b79421b8da71d9272dbad..1900321d2dc835d3a2ee4592942e10c37e69ae0d 100644 --- a/admin-portal/README.adoc +++ b/admin-portal/README.adoc @@ -1,4 +1,4 @@ = Admin Portal :sectnums: -See link:../docs/frontend[here]. \ No newline at end of file +See link:../docs/frontend.adoc[here]. \ No newline at end of file diff --git a/admin-portal/src/lib/components/table/Table.tsx b/admin-portal/src/lib/components/table/Table.tsx index ff6cb25229e725eedbc75eafc857e6de748d96b1..8ae7780182bed783e67a4de5d712a2e52e9546bb 100644 --- a/admin-portal/src/lib/components/table/Table.tsx +++ b/admin-portal/src/lib/components/table/Table.tsx @@ -72,6 +72,7 @@ export function Table<TData extends UniqueEntity>( const tableStyle: SxProps = { "--TableCell-paddingY": (theme) => theme.spacing(1), "--TableCell-paddingX": (theme) => theme.spacing(1.5), + tableLayout: "auto", }; return ( diff --git a/admin-portal/src/lib/components/table/TableRow.tsx b/admin-portal/src/lib/components/table/TableRow.tsx index 40c7801924dc7ac50435fd27e69fd037953c1800..8737792234ffd8ac8e5b4e509bf93591e0070cc6 100644 --- a/admin-portal/src/lib/components/table/TableRow.tsx +++ b/admin-portal/src/lib/components/table/TableRow.tsx @@ -5,12 +5,7 @@ import { Box, styled } from "@mui/joy"; import { Row, Table, flexRender } from "@tanstack/react-table"; -import { - PropsWithChildren, - createElement, - useLayoutEffect, - useRef, -} from "react"; +import { PropsWithChildren, createElement, useRef } from "react"; import { isFunction } from "remeda"; import { CellStyle } from "@/lib/components/table/Table"; @@ -20,8 +15,6 @@ const StyledRow = styled("tr")<{ $subRow: boolean }>(({ theme, $subRow }) => ({ color: $subRow ? theme.palette.warning.plainColor + "!important" : undefined, })); -const OVERFLOW_LEFT = "overflow-left"; - const StyledCell = styled("td")<{ $cellStyle?: CellStyle }>(({ theme, $cellStyle, @@ -106,23 +99,5 @@ export function TableRow<TData>({ function CellContainer({ children }: Readonly<PropsWithChildren>) { const ref = useRef<HTMLSpanElement>(); - - useLayoutEffect(() => { - const span = ref.current; - const td = span?.parentElement; - const tr = td?.parentElement; - if (!span || !td || !tr) { - return; - } - const overflow = span.scrollWidth - td.clientWidth; - const rightSpace = - tr.getBoundingClientRect().right - td.getBoundingClientRect().right; - if (overflow > 0 && rightSpace < overflow) { - span.classList.add(OVERFLOW_LEFT); - } else { - span.classList.remove(OVERFLOW_LEFT); - } - }, [children]); - return <SBox ref={ref}>{children}</SBox>; } diff --git a/admin-portal/src/lib/components/table/TextInputFilter.tsx b/admin-portal/src/lib/components/table/TextInputFilter.tsx index c2e18464c5326a9e8ad5184bfe1f22d185c38f09..76640a80a6c4fec4a4473c28c6230b60ea39b752 100644 --- a/admin-portal/src/lib/components/table/TextInputFilter.tsx +++ b/admin-portal/src/lib/components/table/TextInputFilter.tsx @@ -4,7 +4,6 @@ */ import { Autocomplete } from "@mui/joy"; -import { SxProps } from "@mui/joy/styles/types"; import { useSearchParams } from "next/navigation"; import { useReplaceSearchParams } from "@/lib/hooks/useReplaceSearchParams"; @@ -14,7 +13,6 @@ export function TextInputFilter( searchParamName: string; placeholder?: string; options: string[]; - sx?: SxProps; }>, ) { const searchParams = useSearchParams(); @@ -34,9 +32,6 @@ export function TextInputFilter( ]); }} size="sm" - sx={{ - ...props.sx, - }} placeholder={props.placeholder} aria-label={props.placeholder} options={props.options} diff --git a/admin-portal/src/lib/components/table/cell/ActiveCell.tsx b/admin-portal/src/lib/components/table/cell/ActiveCell.tsx index d3b0d0d9a0ead422c87d06005e4d7ef4b4fa687b..4131f39e008e1b554f39a6114efb7fea97859655 100644 --- a/admin-portal/src/lib/components/table/cell/ActiveCell.tsx +++ b/admin-portal/src/lib/components/table/cell/ActiveCell.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { Stack, Switch } from "@mui/joy"; +import { Switch } from "@mui/joy"; import { CellContext } from "@tanstack/react-table"; import { ReactNode } from "react"; @@ -103,16 +103,6 @@ export function InteractiveActiveCell<TData extends OrgUnit | Actor | Rule>( ); } -export function ActiveCell<TData extends OrgUnit | Actor | Rule>( - props: CellContext<TData, boolean>, -): ReactNode { - return ( - <Stack justifyContent="center" direction="row"> - {getActiveLabel(props.getValue())} - </Stack> - ); -} - export function getActiveLabel<TValue>(flag: TValue): string { return flag ? "✅" : "âŒ"; } diff --git a/admin-portal/src/lib/components/table/cell/EditableActiveCell.tsx b/admin-portal/src/lib/components/table/cell/EditableActiveCell.tsx index 72381b8a6f15ed95a947172070225b0e5eae5a12..ea89c62604466b3bf975fe905b1b8b6d60ab3ed9 100644 --- a/admin-portal/src/lib/components/table/cell/EditableActiveCell.tsx +++ b/admin-portal/src/lib/components/table/cell/EditableActiveCell.tsx @@ -7,15 +7,9 @@ import { Switch } from "@mui/joy"; import { CellContext } from "@tanstack/react-table"; import { ChangeEvent, ReactNode, useCallback } from "react"; -import { - ActiveCell, - InteractiveActiveCell, -} from "@/lib/components/table/cell/ActiveCell"; +import { InteractiveActiveCell } from "@/lib/components/table/cell/ActiveCell"; import { Actor } from "@/lib/components/view/actors/ActorTable"; -import { - isOneOfStagedEntity, - useEditableRow, -} from "@/lib/helpers/entityFilter"; +import { isOneOfStagedEntity } from "@/lib/helpers/entityFilter"; import { OrgUnit } from "@/lib/hooks/useOrgUnits"; import { Rule } from "@/lib/hooks/useRules"; @@ -32,21 +26,13 @@ export function EditableActiveCell<TData extends OrgUnit | Actor | Rule>( [props.row, props.table.options.meta], ); - const isEditableRow = useEditableRow(props.row); - if (!isOneOfStagedEntity(props.row.original)) { return <InteractiveActiveCell {...props} />; } - if (isEditableRow) { - return <ActiveCell {...props} />; - } - - const value = props.getValue(); - return ( <Switch - checked={value} + checked={props.getValue()} onChange={handleChange} onClick={(event) => event.stopPropagation()} /> diff --git a/admin-portal/src/lib/components/table/head/Header.tsx b/admin-portal/src/lib/components/table/head/Header.tsx index 34ea1188a3520b4f49fd6cbda76cec978fe597ee..4f01c09607f115a6729cb7c4016c94970e189fa8 100644 --- a/admin-portal/src/lib/components/table/head/Header.tsx +++ b/admin-portal/src/lib/components/table/head/Header.tsx @@ -14,16 +14,12 @@ import { PropsWithChildren } from "react"; import { EDIT_BUTTON_ID } from "@/lib/components/table/addEditColumns"; import { TOGGLE_EXPAND_ID } from "@/lib/helpers/addFeatureColumns"; -const StyledHeaderCell = styled("th")<{ width?: number | string }>( - ({ theme, width }) => ({ - width, - "--TableCell-paddingY": theme.spacing(1.5), - "--TableCell-paddingX": theme.spacing(1.5), - }), -); +const StyledHeaderCell = styled("th")(({ theme }) => ({ + "--TableCell-paddingY": theme.spacing(1.5), + "--TableCell-paddingX": theme.spacing(1.5), +})); export type HeaderProps = PropsWithChildren<{ - width?: number | string; canSort: boolean; isSorted: false | SortDirection; onSort?: (event: unknown) => void; @@ -41,7 +37,6 @@ export function Header(props: HeaderProps) { return ( <StyledHeaderCell role={isLink ? "columnheader" : "none"} - width={props.width} aria-label={isLink ? props.label : undefined} id={props.id} > diff --git a/admin-portal/src/lib/components/table/head/TableHead.tsx b/admin-portal/src/lib/components/table/head/TableHead.tsx index 21846a0b597ba5324bcc7a5dd9d5fbfa6a9c1c7a..77178bf44e018f14a0e922af37cd4214009efe53 100644 --- a/admin-portal/src/lib/components/table/head/TableHead.tsx +++ b/admin-portal/src/lib/components/table/head/TableHead.tsx @@ -37,7 +37,6 @@ export function TableHead< <Fragment key={column.id}> <Header key={header.id} - width={meta?.width} canSort={column.getCanSort()} isSorted={column.getIsSorted()} onSort={column.getToggleSortingHandler()} @@ -70,6 +69,7 @@ export function TableHead< header.column.id != TOGGLE_EXPAND_ID ? undefined : "none" } key={header.column.id} + style={{ maxWidth: "0" }} > <Filter table={props.reactTable} column={header.column} /> </th> diff --git a/admin-portal/src/lib/components/timeline/TimelineEntry.tsx b/admin-portal/src/lib/components/timeline/TimelineEntry.tsx index b143e8e86e381856247d4976d5719c04a4b247f0..0da2df02f475208959d92ce9ab569f3ede40edf5 100644 --- a/admin-portal/src/lib/components/timeline/TimelineEntry.tsx +++ b/admin-portal/src/lib/components/timeline/TimelineEntry.tsx @@ -79,7 +79,9 @@ function Content(props: PropsWithChildren<TitleAndLabel>) { </> )} </Typography> - <Stack spacing={1}>{props.children}</Stack> + <Stack flexDirection="column" spacing={1}> + {props.children} + </Stack> </> ); } diff --git a/admin-portal/src/lib/components/view/audit-log/tables/AuditActorMetadataTable.tsx b/admin-portal/src/lib/components/view/audit-log/tables/AuditActorMetadataTable.tsx index 4bf55e026056c8c0112f1e3572c14d6a7724141c..922b4319282bf2e5d31b21fac511d08820c9da15 100644 --- a/admin-portal/src/lib/components/view/audit-log/tables/AuditActorMetadataTable.tsx +++ b/admin-portal/src/lib/components/view/audit-log/tables/AuditActorMetadataTable.tsx @@ -37,9 +37,6 @@ const columns = [ header: "", enableGlobalFilter: false, cell: RevisionTypeCell, - meta: { - width: "48px", - }, }), accessor("id", { enableGlobalFilter: false, diff --git a/admin-portal/src/lib/components/view/audit-log/tables/AuditActorTable.tsx b/admin-portal/src/lib/components/view/audit-log/tables/AuditActorTable.tsx index cb6bbef101ee3857bb099a2f2e31a4617f9c5f56..f651f83993533e383ed99011c117d924369a96a2 100644 --- a/admin-portal/src/lib/components/view/audit-log/tables/AuditActorTable.tsx +++ b/admin-portal/src/lib/components/view/audit-log/tables/AuditActorTable.tsx @@ -46,9 +46,6 @@ const columns = [ header: "", enableGlobalFilter: false, cell: RevisionTypeCell, - meta: { - width: "48px", - }, }), accessor("readableName", { cell: AuditCell, @@ -65,16 +62,10 @@ const columns = [ accessor("type", { cell: AuditCell, enableGlobalFilter: false, - meta: { - width: "5%", - }, }), accessor("active", { cell: AuditCell, enableGlobalFilter: false, - meta: { - width: "5%", - }, }), accessor("currentCertificate", { cell: AuditCell, diff --git a/admin-portal/src/lib/components/view/audit-log/tables/AuditOrgUnitTable.tsx b/admin-portal/src/lib/components/view/audit-log/tables/AuditOrgUnitTable.tsx index 4965b252ca38fe78efd0503caa93988ff0c3212a..8df002a85498d657d97be401b5545c6b328b67aa 100644 --- a/admin-portal/src/lib/components/view/audit-log/tables/AuditOrgUnitTable.tsx +++ b/admin-portal/src/lib/components/view/audit-log/tables/AuditOrgUnitTable.tsx @@ -42,9 +42,6 @@ const columns = [ header: "", enableGlobalFilter: false, cell: RevisionTypeCell, - meta: { - width: "48px", - }, }), accessor("readableName", { cell: AuditCell, @@ -53,23 +50,14 @@ const columns = [ accessor("type", { cell: AuditCell, enableGlobalFilter: false, - meta: { - width: "20%", - }, }), accessor("federalState", { cell: AuditCell, enableGlobalFilter: false, - meta: { - width: "20%", - }, }), accessor("active", { cell: AuditCell, enableGlobalFilter: false, - meta: { - width: "20%", - }, }), ]; diff --git a/admin-portal/src/lib/components/view/audit-log/tables/AuditRuleTable.tsx b/admin-portal/src/lib/components/view/audit-log/tables/AuditRuleTable.tsx index bf8a71513ade1a86f02ab9188cc861a3ea3829d1..95ced0e914b8b0f38949ab226c006f35415e7c40 100644 --- a/admin-portal/src/lib/components/view/audit-log/tables/AuditRuleTable.tsx +++ b/admin-portal/src/lib/components/view/audit-log/tables/AuditRuleTable.tsx @@ -41,16 +41,10 @@ const columns = [ header: "", enableGlobalFilter: false, cell: RevisionTypeCell, - meta: { - width: "48px", - }, }), accessor("description", { cell: AuditCell, enableGlobalFilter: false, - meta: { - width: "15%", - }, }), accessor("client", { cell: AuditCell, @@ -63,9 +57,6 @@ const columns = [ accessor("active", { cell: AuditCell, enableGlobalFilter: false, - meta: { - width: "5%", - }, }), ]; diff --git a/admin-portal/src/lib/components/view/legal/LegalLinkList.tsx b/admin-portal/src/lib/components/view/legal/LegalLinkList.tsx index 0fcc9202da93b94180d1aaff80f9e337983debe2..412c31fcedd77488da0bee136b534523e94ac849 100644 --- a/admin-portal/src/lib/components/view/legal/LegalLinkList.tsx +++ b/admin-portal/src/lib/components/view/legal/LegalLinkList.tsx @@ -5,15 +5,7 @@ "use client"; -import { - Accessibility, - Email, - Handshake, - History, - Info, - Lock, - ThumbUp, -} from "@mui/icons-material"; +import { Email, History, ThumbUp } from "@mui/icons-material"; import { List, ListItem, @@ -55,10 +47,6 @@ function LegalLink({ export function LegalLinkList() { return ( <List sx={{ width: "max-content", flexGrow: 0 }}> - <LegalLink category="imprint" startDecorator={<Info />} /> - <LegalLink category="termsOfUse" startDecorator={<Handshake />} /> - <LegalLink category="accessibility" startDecorator={<Accessibility />} /> - <LegalLink category="privacy" startDecorator={<Lock />} /> <LegalLink category="acknowledgements" startDecorator={<ThumbUp />} /> <LegalLink category="contact" startDecorator={<Email />} /> <LegalLink category="releaseNotes" startDecorator={<History />} /> diff --git a/admin-portal/src/lib/hooks/useAuditLogs.ts b/admin-portal/src/lib/hooks/useAuditLogs.ts index ee5f9e715dd03093a261776ee207ae4c58e1323b..f04904e344b9b1909b89cab92b740a82d0afb3fa 100644 --- a/admin-portal/src/lib/hooks/useAuditLogs.ts +++ b/admin-portal/src/lib/hooks/useAuditLogs.ts @@ -22,8 +22,11 @@ function fetchUsernames( (response) => { return response.usernames; }, - (error: BackendError) => { - throw new Error(error.status.toString()); + (error: BackendError | Error) => { + if (error.message.startsWith("Failed to fetch")) + throw new Error("FetchFailed"); + if ("status" in error) throw new Error(error.status.toString()); + else throw new Error(error.message); }, ); }; @@ -47,8 +50,11 @@ function fetchRevisions( ...r, id: r.id.toString(), })), - (error: BackendError) => { - throw new Error(error.status.toString()); + (error: BackendError | Error) => { + if (error.message.startsWith("Failed to fetch")) + throw new Error("FetchFailed"); + if ("status" in error) throw new Error(error.status.toString()); + else throw new Error(error.message); }, ); }; @@ -62,8 +68,11 @@ function fetchExport( (response) => { return response; }, - (error: BackendError) => { - throw new Error(error.status.toString()); + (error: BackendError | Error) => { + if (error.message.startsWith("Failed to fetch")) + throw new Error("FetchFailed"); + if ("status" in error) throw new Error(error.status.toString()); + else throw new Error(error.message); }, ); }; diff --git a/admin-portal/src/lib/hooks/useOrgUnits.ts b/admin-portal/src/lib/hooks/useOrgUnits.ts index ee3923378aeaa268e5439b2c8eef1392be4ddee0..ee900ee724dbf0bbb98257cbccafb45324c44f68 100644 --- a/admin-portal/src/lib/hooks/useOrgUnits.ts +++ b/admin-portal/src/lib/hooks/useOrgUnits.ts @@ -67,8 +67,11 @@ export function fetchOrgUnits( stagedOrgUnits: sortBy(response.stagedOrgUnits, id), }; }, - (error: BackendError) => { - throw new Error(error.status.toString()); + (error: BackendError | Error) => { + if (error.message.startsWith("Failed to fetch")) + throw new Error("FetchFailed"); + if ("status" in error) throw new Error(error.status.toString()); + else throw new Error(error.message); }, ); }; diff --git a/admin-portal/src/lib/hooks/useRules.ts b/admin-portal/src/lib/hooks/useRules.ts index 4c8528b3cf9e17dc83e39219705371cb04985975..839492077ff5e5deec213b82665e4c95b762c775 100644 --- a/admin-portal/src/lib/hooks/useRules.ts +++ b/admin-portal/src/lib/hooks/useRules.ts @@ -56,8 +56,11 @@ export function fetchRules(adminApi: ServiceDirectoryAdminApi) { stagedRules: sortBy(response.stagedRules, id), }; }, - (error: BackendError) => { - throw new Error(error.status.toString()); + (error: BackendError | Error) => { + if (error.message.startsWith("Failed to fetch")) + throw new Error("FetchFailed"); + if ("status" in error) throw new Error(error.status.toString()); + else throw new Error(error.message); }, ); }; diff --git a/admin-portal/src/lib/i18n/locales/de/translation.json b/admin-portal/src/lib/i18n/locales/de/translation.json index 4703fdf321b0b71f2a1b7838b26af2b1527d033a..dcae694b859f235edfe136aaf0311f5a000b6c02 100644 --- a/admin-portal/src/lib/i18n/locales/de/translation.json +++ b/admin-portal/src/lib/i18n/locales/de/translation.json @@ -100,7 +100,10 @@ "entityCart": "Entitäten genehmigen", "error": "Fehler", "errorReason": { - "502": "Es konnte keine Verbindung zum Backend-Server hergestellt werden." + "404": "Die Ressource wurde nicht gefunden.", + "500": "Es ist ein interner Server-Fehler aufgetreten.", + "502": "Es konnte keine Verbindung zum Backend-Server hergestellt werden.", + "FetchFailed": "Die Ressource konnte nicht abgerufen werden." }, "expandRow": "Zeile ausklappen", "expensiveQuery": "Dies ist eine potenziell aufwendige Abfrage", @@ -114,43 +117,47 @@ "importConfigLabel": "Wählen Sie eine JSON-Datei aus", "importHeader": "Konfiguration importieren", "legal": { - "accessibility": { - "content": "Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie vom Gesundheitsamt freigegeben sind.", - "title": "Erklärung zur Barrierefreiheit" - }, "acknowledgements": { - "content": "Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie vom Gesundheitsamt freigegeben sind.", + "content": [ + "<p>GA-Lotse verwendet die folgenden externen Ressourcen:</p>", + "<section>", + " <h3>Verwendete Libraries</h3>", + " <p>Verwendete Open Source Bibliotheken finden sich in den jeweiligen Paketen im Repository auf <a href=\"https://gitlab.opencode.de/ga-lotse/ga-lotse-code\">OpenCoDE</a>.</p>", + "</section>" + ], "title": "Danksagung" }, "contact": { - "content": "Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie vom Gesundheitsamt freigegeben sind.", + "content": [ + "<table>", + " <tr><th colspan=2 style=\"text-align: left\">Telefonische Erreichbarkeit:</th></tr>", + " <tr><td>Telefon:</td><td>+49 (0) 800-4256873</td></tr>", + " <tr><td> </td><td></td></tr>", + " <tr><td>Montag - Donnerstag:</td><td>07:30 Uhr - 16:00 Uhr</td></tr>", + " <tr><td>Freitag:</td><td>07:30 Uhr - 14:00 Uhr</td></tr>", + " <tr><td> </td><td></td></tr>", + " <tr><th colspan=2 style=\"text-align: left\">Erreichbarkeit via Ticketsystem:</th></tr>", + " <tr><td>E-Mail:</td><td><a href=\"mailto:support@ga-lotse.de\">support@ga-lotse.de</a></td></tr>", + " <tr><td>Open Source:</td><td><a href=\"https://gitlab.opencode.de/ga-lotse\">OpenCoDE</a></td></tr>", + "</table>" + ], "title": "Kontakt" }, - "imprint": { - "content": "Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie vom Gesundheitsamt freigegeben sind.", - "title": "Impressum" - }, - "privacy": { - "content": "Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie vom Gesundheitsamt freigegeben sind.", - "title": "Datenschutzerklärung" - }, "releaseNotes": { "content": [ - "<h2>GA-Lotse 1.0</h2>", - "<h3>01.10.2024</h3>", - "<ul>", - " <li>Einrichtung einer Service-Mesh-Infrastruktur zwischen verschiedenen Gesundheitsämtern, Aktoren und Organisationseinheiten</li>", - " <li>Regelwerk zur Ãœberprüfung zulässiger Verbindungen</li>", - " <li>Administration von Org-Units, Aktoren und Regeln</li>", - " <li>Export der Service-Directory-Konfiguration</li>", - " <li>Ansicht und Export des Auditprotokolls</li>", - "</ul>" + "<section>", + " <h3>GA-Lotse 1.0</h3>", + " <h4>01.10.2024</h4>", + " <ul>", + " <li>Einrichtung einer Service-Mesh-Infrastruktur zwischen verschiedenen Gesundheitsämtern, Aktoren und Organisationseinheiten</li>", + " <li>Regelwerk zur Ãœberprüfung zulässiger Verbindungen</li>", + " <li>Administration von Org-Units, Aktoren und Regeln</li>", + " <li>Export der Service-Directory-Konfiguration</li>", + " <li>Ansicht und Export des Auditprotokolls</li>", + " </ul>", + "</section>" ], "title": "Release Notes" - }, - "termsOfUse": { - "content": "Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie vom Gesundheitsamt freigegeben sind.", - "title": "Nutzungsbedingungen" } }, "navigation": { diff --git a/admin-portal/src/lib/i18n/locales/en/translation.json b/admin-portal/src/lib/i18n/locales/en/translation.json index b321cf993bb78b0d0b7ab21f7d4e44cd165a39fe..aa095ff4269dc19a28e8c9f9e1c8146684322337 100644 --- a/admin-portal/src/lib/i18n/locales/en/translation.json +++ b/admin-portal/src/lib/i18n/locales/en/translation.json @@ -100,7 +100,10 @@ "entityCart": "Approve entities", "error": "Error", "errorReason": { - "502": "Could not reach Backend Server." + "404": "Could not find resource.", + "500": "An internal server error occurred.", + "502": "Could not reach Backend Server.", + "FetchFailed": "Could not fetch resource." }, "expandRow": "Expand row", "expensiveQuery": "This is a potentially expensive query", @@ -114,43 +117,47 @@ "importConfigLabel": "Choose a JSON file", "importHeader": "Configuration Import", "legal": { - "accessibility": { - "content": "The page is still under construction. The content will be updated as soon as it is approved by the health department.", - "title": "Accessibility" - }, "acknowledgements": { - "content": "The page is still under construction. The content will be updated as soon as it is approved by the health department.", + "content": [ + "<p>GA-Lotse uses the following external resources:</p>", + "<section>", + " <h3>Libraries used</h3>", + " <p>Open source libraries used can be found in the respective packages in the repository on <a href=\"https://gitlab.opencode.de/ga-lotse/ga-lotse-code\">OpenCoDE</a>.</p>", + "</section>" + ], "title": "Acknowledgements" }, "contact": { - "content": "The page is still under construction. The content will be updated as soon as it is approved by the health department.", + "content": [ + "<table>", + " <tr><th colspan=2 style=\"text-align: left\">Availability by telephone:</th></tr>", + " <tr><td>Telefon:</td><td>+49 (0) 800-4256873</td></tr>", + " <tr><td> </td><td></td></tr>", + " <tr><td>Monday - Thursday:</td><td>07:30 h - 16:00 h</td></tr>", + " <tr><td>Friday:</td><td>07:30 h - 14:00 h</td></tr>", + " <tr><td> </td><td></td></tr>", + " <tr><th colspan=2 style=\"text-align: left\">Availability via ticket system:</th></tr>", + " <tr><td>e-mail:</td><td><a href=\"mailto:support@ga-lotse.de\">support@ga-lotse.de</a></td></tr>", + " <tr><td>Open Source:</td><td><a href=\"https://gitlab.opencode.de/ga-lotse\">OpenCoDE</a></td></tr>", + "</table>" + ], "title": "Contact" }, - "imprint": { - "content": "The page is still under construction. The content will be updated as soon as it is approved by the health department.", - "title": "Imprint" - }, - "privacy": { - "content": "The page is still under construction. The content will be updated as soon as it is approved by the health department.", - "title": "Privacy policy" - }, "releaseNotes": { "content": [ - "<h2>GA-Lotse 1.0</h2>", - "<h3>2024-10-01</h3>", - "<ul>", - " <li>Establishing a service mesh infrastructure between different healthcare departments, actors and organizational units</li>", - " <li>Rules for checking permitted connections</li>", - " <li>Administration of OrgUnits, Actors and Rules</li>", - " <li>Export of the Service Directory configuration</li>", - " <li>Display and export of AuditLog</li>", - "</ul>" + "<section>", + " <h3>GA-Lotse 1.0</h3>", + " <h4>2024-10-01</h4>", + " <ul>", + " <li>Establishing a service mesh infrastructure between different healthcare departments, actors and organizational units</li>", + " <li>Rules for checking permitted connections</li>", + " <li>Administration of OrgUnits, Actors and Rules</li>", + " <li>Export of the Service Directory configuration</li>", + " <li>Display and export of AuditLog</li>", + " </ul>", + "</section>" ], "title": "Release Notes" - }, - "termsOfUse": { - "content": "The page is still under construction. The content will be updated as soon as it is approved by the health department.", - "title": "Terms of use" } }, "navigation": { diff --git a/backend/README.md b/backend/README.md index cbc5fefdd405a4cdd6e3f18f1bdd4f2f3310bef8..ab1f208cf52d8801be81aff38b051ada3473262d 100644 --- a/backend/README.md +++ b/backend/README.md @@ -2,37 +2,42 @@ This project uses a gradle [multi project build](https://docs.gradle.org/current/userguide/multi_project_builds.html). -After importing in intellij make sure to switch to adoptium temurin jdk 21. A good way to install and manage jdks -is [sdkman](https://sdkman.io/) +After importing in intellij make sure to switch to Eclipse Temurin JDK 21. A good way to install and manage jdks +is [sdkman](https://sdkman.io/). -By setting the system property `-Deshg.testcontainers.enabled=false` unit tests do not start testcontainers to speed up +Docker (26 or newer) and docker compose (2.27 or newer) are needed to run the `composeUp` gradle tasks. + +By setting the system property `-Deshg.testcontainers.enabled=false`, unit tests do not start testcontainers to speed up test execution during development. Developers must provide alternatives to connect to like a local DB. A IntelliJ run configuration template for unit tests is provided. # Login Information -During the initial setup, the [TestUser](lib-keycloak/src/main/java/de/eshg/lib/keycloak/TestUser.java) is used to -configure -test users with the specified credentials in our keycloak service. -The current credentials used for development purposes are: - -| Username | Password | Scope | -| ---------------------- | -------- | ----------------------------------------------------------------------- | -| admin | admin | Keycloak admin | -| dummy | password | all permissions | -| tm_user | password | travel medicine user | -| inspection_ga_user | password | inspection standard user of a "Gesundheitsamt" | -| inspection_ga_config | password | inspection user of a "Gesundheitsamt" able to edit inspection templates | -| inspection_ga_teamlead | password | inspection team leader of a "Gesundheitsamt" | -| inspection_la_user | password | inspection user of a "Landesamt" | +During the initial setup, the [EmployeeTestUser](lib-keycloak/src/main/java/de/eshg/lib/keycloak/EmployeeTestUser.java) is used to +configure test users with the specified credentials in our keycloak service. +Some of the current credentials used for development purposes are: + +| Username | Password | Scope | +|----------------------- | -------- | ------------------------------------------------------------------------ | +| admin | admin | Keycloak admin | +| dummy | password | all permissions | +| tm_user | password | travel medicine user | +| inspection_ga_user | password | inspection standard user of a "Gesundheitsamt" | +| inspection_ga_config | password | inspection user of a "Gesundheitsamt" able to edit inspection templates | +| inspection_ga_teamlead | password | inspection team leader of a "Gesundheitsamt" | +| inspection_la_user | password | inspection user of a "Landesamt" | +| ... | password | ... | + +Note: The provisioning of these test users is controlled in the `base` module with the system property `eshg.keycloak.provision-test-users`. +Passwords can only be used to login if `eshg.keycloak.allow-passwords-for-employees` is `true` (default with `:base:composeUp`). # Starting the backend application ## as a whole (dockerized) -To start the backend application as a whole run `./gradlew composeUp`. Note that this will -start the application built from source as-is in your checkout. To shut down the backend -application run `./gradlew composedown`. +To start the backend application for local testing, run `./gradlew composeUp`. Note that this will +start the application built from source as-is in your checkout and enable the `test-helper` profile for local testing. +To shut down the backend application run `./gradlew composeDown`. ## Preview Features @@ -97,12 +102,12 @@ start the application - built from source as-is in your checkout. - `./gradlew service-directory:composeUp` - `./gradlew travel-medicine:composeUp` - `./gradlew measles-protection:composeUp` +- ... Shutting down individual modules can be done using the respective counterpart `./gradlew <GRADLE_MODULE>:composeDown`. -Keycloak is started as a dependency of the base module's `composeUp`. -It will run on port 9090. It's db will run on port 5436. +Keycloak and maildev are started as a dependency of the base module's `composeUp`. ## individual modules (bootRun) @@ -116,17 +121,21 @@ We use gradle's [dependency locking mechanism](https://docs.gradle.org/current/u the [spring dependency-management plugin](https://docs.spring.io/dependency-management-plugin/docs/current/reference/html/). Wherever possible we use dependencies versions that are given via the spring dependency-management plugin, if the -desired dependency is not managed via the said plugin, we use strive to use `latest.release` as version and lock the +desired dependency is not managed via the said plugin, we strive to use `latest.release` as version and lock the version as explained in the following sections. +The version of keycloak is controlled using a version catalog in `settings.gradle`, to ensure all keycloak related dependencies use the same version. + **When introducing / updating dependencies please avoid version conflicts! Review the lockfile changes thoroughly** ## Introducing new dependencies -Introduce new dependencies as usual by adding them to the [build.gradle](build.gradle) file. Afterwards update the +Before integrating a new dependency, please consider if the dependency is necessary. Follow the guidelines in the [Dependency Management Guide](../docs/dependency-management.adoc#check-if-the-dependency-is-necessary-and-reasonable). + +Introduce new dependencies as usual by adding them to the [build.gradle](build.gradle) file. Then update the dependency lock-files for the new dependency, and it's transitive dependencies: -Example: +**Example:** You added to `build.gradle`: @@ -146,7 +155,7 @@ to update locks also of all dependent modules. To do this, run ## Selectively updating dependencies -Updating a single dependency works just as adding it. Given the dependency is specified with `latest.release`, updating +Updating a single dependency works the same as adding it. Given the dependency is specified with `latest.release`, updating the locks will update the dependency. For more hints / instructions on how to selectively update a single dependency (or multiple, but not all) see [Selectively updating lock state entries](https://docs.gradle.org/current/userguide/dependency_locking.html#selectively_updating_lock_state_entries) @@ -213,36 +222,21 @@ you can use the versioned [`.git-blame-ignore-revs`](../.git-blame-ignore-revs) git config blame.ignoreRevsFile .git-blame-ignore-revs -### Merge request pipeline features - -Merge request pipelines currently support the following features:\ -Overall test coverage percentage is displayed on the MR page below the current pipeline status. -Additionally, the coverage is visualized in the MR diff, -see [GitLab Test coverage visualization](https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html) -for details.\ -The test and coverage reports are also available as artifacts in the build-job. -Most reports can be viewed in the browser without downloading them. -There is also a code quality check, whose reports can be viewed in three places: - -- As a widget in the MR page, just below the approval section -- As a tab in each MR-Pipeline -- As a html report artifact in the `code_quality_html_report` - ## Reference Documentation For further reference, please consider the following sections: - [Official Gradle documentation](https://docs.gradle.org) -- [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.1.5/gradle-plugin/reference/html/) -- [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.1.5/gradle-plugin/reference/html/#build-image) -- [Spring Boot Testcontainers support](https://docs.spring.io/spring-boot/docs/3.1.5/reference/html/features.html#features.testing.testcontainers) +- [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/gradle-plugin/index.html) +- [Create an OCI image](https://docs.spring.io/spring-boot/gradle-plugin/packaging-oci-image.html) +- [Spring Boot Testcontainers support](https://docs.spring.io/spring-boot/reference/testing/testcontainers.html) - [Testcontainers Postgres Module Reference Guide](https://java.testcontainers.org/modules/databases/postgres/) -- [Spring Security](https://docs.spring.io/spring-boot/docs/3.1.5/reference/htmlsingle/index.html#web.security) -- [Spring Web](https://docs.spring.io/spring-boot/docs/3.1.5/reference/htmlsingle/index.html#web) -- [OAuth2 Resource Server](https://docs.spring.io/spring-boot/docs/3.1.5/reference/htmlsingle/index.html#web.security.oauth2.server) -- [Spring Data JPA](https://docs.spring.io/spring-boot/docs/3.1.5/reference/htmlsingle/index.html#data.sql.jpa-and-spring-data) -- [Validation](https://docs.spring.io/spring-boot/docs/3.1.5/reference/htmlsingle/index.html#io.validation) -- [Spring Boot Actuator](https://docs.spring.io/spring-boot/docs/3.1.5/reference/htmlsingle/index.html#actuator) +- [Spring Security](https://docs.spring.io/spring-boot/reference/web/spring-security.html) +- [Spring Web](https://docs.spring.io/spring-boot/reference/web/index.html) +- [OAuth2 Resource Server](https://docs.spring.io/spring-boot/reference/web/spring-security.html#web.security.oauth2.server) +- [Spring Data JPA](https://docs.spring.io/spring-boot/reference/data/sql.html#data.sql.jpa-and-spring-data) +- [Validation](https://docs.spring.io/spring-boot/reference/io/validation.html) +- [Spring Boot Actuator](https://docs.spring.io/spring-boot/reference/actuator/enabling.html) - [Testcontainers](https://java.testcontainers.org/) ## Guides diff --git a/backend/api-commons/gradle.lockfile b/backend/api-commons/gradle.lockfile index 06dbb2ff09463c86d7b0f212437a6699ede95eaf..8017562d7c3154dd506763857adba48e3e63daef 100644 --- a/backend/api-commons/gradle.lockfile +++ b/backend/api-commons/gradle.lockfile @@ -1,15 +1,15 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -46,21 +46,21 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/api-commons/src/main/java/de/eshg/api/commons/CanBeLogged.java b/backend/api-commons/src/main/java/de/eshg/api/commons/CanBeLogged.java deleted file mode 100644 index 0db233a6b0a2cb4440ae55c12f9d95087c60c4f8..0000000000000000000000000000000000000000 --- a/backend/api-commons/src/main/java/de/eshg/api/commons/CanBeLogged.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.api.commons; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ - ElementType.ANNOTATION_TYPE, - ElementType.METHOD, - ElementType.CONSTRUCTOR, - ElementType.FIELD, - ElementType.PARAMETER -}) -@Retention(RetentionPolicy.RUNTIME) -public @interface CanBeLogged {} diff --git a/backend/auditlog-api/gradle.lockfile b/backend/auditlog-api/gradle.lockfile index 13cdc1dc47e2d36cd5c9e795196911810263c462..f60d03e22d075439c1b6051f93bd529783a3e135 100644 --- a/backend/auditlog-api/gradle.lockfile +++ b/backend/auditlog-api/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -11,9 +11,9 @@ com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2=compileClasspath,p com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -54,21 +54,21 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogApi.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogApi.java index f12d928948a6b5d0cabe7463b878ebf2925a7e0a..62b859585b59e83fe5f172c1616d603b412682d0 100644 --- a/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogApi.java +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogApi.java @@ -15,6 +15,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import java.io.IOException; import org.springdoc.core.annotations.ParameterObject; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.service.annotation.GetExchange; @@ -40,17 +41,21 @@ public interface AuditLogApi { @GetExchange @Operation(summary = "Decrypt and read an auditlog file for a service of a certain date.") - String readAuditLogFile( + ResponseEntity<String> readAuditLogFile( @RequestHeader(name = DECRYPTION_KEY_HEADER_NAME) @NotNull @NotBlank String key, @InlineParameterObject @ParameterObject @Valid ReadAuditLogFileRequest readAuditLogFileRequest) throws IOException; - @GetExchange("/grantees") + @GetExchange("/grantees-candidates") @Operation(summary = "List all user candidates for audit log grant access.") - GetUsersResponse getValidAuditLogGrantees( - @InlineParameterObject @ParameterObject @Valid - GetValidAuditLogGranteesRequest getValidAuditLogGranteesRequest); + GetUsersResponse getAuditLogGranteesCandidates( + @InlineParameterObject @ParameterObject @Valid GetAuditLogDataRequest getAuditLogDataRequest); + + @GetExchange("/grant-access") + @Operation(summary = "List all granted accesses of audit log.") + GetAuditLogGrantedAccessesResponse getAuditLogGrantedAccesses( + @InlineParameterObject @ParameterObject @Valid GetAuditLogDataRequest getAuditLogDataRequest); @PostExchange("/grant-access") @Operation( diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogGrantedAccessDto.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogGrantedAccessCountDto.java similarity index 81% rename from backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogGrantedAccessDto.java rename to backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogGrantedAccessCountDto.java index 6f35b2a8b3df492b49a2b30fdf8f0952094c664c..582227981097bac64858246520b6d4b5093ff3a0 100644 --- a/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogGrantedAccessDto.java +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogGrantedAccessCountDto.java @@ -9,8 +9,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; -@Schema(name = "AuditLogGrantedAccessDto") -public record AuditLogGrantedAccessDto( +@Schema(name = "AuditLogGrantedAccessCount") +public record AuditLogGrantedAccessCountDto( @NotNull @Valid AuditLogDto auditLog, @NotNull @Schema(description = "Number of users having granted access") int validGrantedAccessCount) {} diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogTestHelperApi.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogTestHelperApi.java index de315e5cc3a1997f9e3d12edd3debcfaf0579263..9b69477100383de58ae84a54e79b4877ad6bad1b 100644 --- a/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogTestHelperApi.java +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/AuditLogTestHelperApi.java @@ -5,21 +5,18 @@ package de.eshg.auditlog; -import static de.eshg.auditlog.AuditLogTestHelperApi.BASE_URL; +import static de.eshg.auditlog.SharedAuditLogTestHelperApi.BASE_URL; -import java.io.IOException; -import org.springframework.web.service.annotation.DeleteExchange; +import de.eshg.auditlog.feature.AuditLogFeature; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.service.annotation.HttpExchange; import org.springframework.web.service.annotation.PostExchange; @HttpExchange(BASE_URL) -public interface AuditLogTestHelperApi { +public interface AuditLogTestHelperApi extends SharedAuditLogTestHelperApi { String BASE_URL = "/test-helper"; - @DeleteExchange("audit-log-storage") - void clearAuditLogStorageDirectory() throws IOException; - - @PostExchange("archiving-job") - void runArchivingJob(); + @PostExchange("/enabled-new-features/{featureToEnable}") + void enableNewFeature(@PathVariable("featureToEnable") AuditLogFeature featureToEnable); } diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetValidAuditLogGranteesRequest.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAuditLogDataRequest.java similarity index 86% rename from backend/auditlog-api/src/main/java/de/eshg/auditlog/GetValidAuditLogGranteesRequest.java rename to backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAuditLogDataRequest.java index 63eb45c33dd2a0d0fe03a12a4892394e77b0767d..47f77fcf9dc876cf8f1671b4f987749e43e2aec0 100644 --- a/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetValidAuditLogGranteesRequest.java +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAuditLogDataRequest.java @@ -9,5 +9,5 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Past; import java.time.LocalDate; -public record GetValidAuditLogGranteesRequest( +public record GetAuditLogDataRequest( @NotNull AuditLogSource source, @NotNull @Past LocalDate date) {} diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAuditLogGrantedAccessesResponse.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAuditLogGrantedAccessesResponse.java new file mode 100644 index 0000000000000000000000000000000000000000..4f70f9a6184b9551044d824551500f975f7eda46 --- /dev/null +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAuditLogGrantedAccessesResponse.java @@ -0,0 +1,17 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.auditlog; + +import de.eshg.base.user.api.UserDto; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public record GetAuditLogGrantedAccessesResponse( + @NotNull @Valid List<GrantedAccessDto> grantedAccesses, + @NotNull @Valid Map<UUID, UserDto> resolvedUsers) {} diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsFilterOptions.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsFilterOptions.java index 37f8915653f34155ad3044687b7978fbc8f6d140..607455cc5c9e439dd276fcadd73785d242178c99 100644 --- a/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsFilterOptions.java +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsFilterOptions.java @@ -9,7 +9,6 @@ import static de.eshg.auditlog.AuditLogApi.QueryParameter.END_DATE; import static de.eshg.auditlog.AuditLogApi.QueryParameter.SOURCE; import static de.eshg.auditlog.AuditLogApi.QueryParameter.START_DATE; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import jakarta.validation.constraints.Past; import java.time.LocalDate; @@ -19,8 +18,7 @@ import org.springframework.web.bind.annotation.BindParam; @ParameterObject public record GetAvailableAuditLogsFilterOptions( - @CanBeLogged - @BindParam(SOURCE) + @BindParam(SOURCE) @Parameter( description = """ @@ -29,8 +27,7 @@ public record GetAvailableAuditLogsFilterOptions( - If not submitted, no filtering takes place """) Set<AuditLogSource> source, - @CanBeLogged - @BindParam(START_DATE) + @BindParam(START_DATE) @Parameter( description = """ @@ -42,8 +39,7 @@ public record GetAvailableAuditLogsFilterOptions( """) @Past LocalDate startDate, - @CanBeLogged - @BindParam(END_DATE) + @BindParam(END_DATE) @Parameter( description = """ diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsPaginationOptions.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsPaginationOptions.java index c132db328dad8d18e9d44032a03e03de97be913b..b95dbadaaeeb4f6743049c2fdeb02e6766ba69a0 100644 --- a/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsPaginationOptions.java +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsPaginationOptions.java @@ -8,7 +8,6 @@ package de.eshg.auditlog; import static de.eshg.auditlog.AuditLogApi.QueryParameter.PAGE_NUMBER; import static de.eshg.auditlog.AuditLogApi.QueryParameter.PAGE_SIZE; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Max; @@ -17,15 +16,13 @@ import java.util.Objects; import org.springframework.web.bind.annotation.BindParam; public record GetAvailableAuditLogsPaginationOptions( - @CanBeLogged - @Parameter(description = "Limit of returned procedures") + @Parameter(description = "Limit of returned procedures") @BindParam(value = PAGE_SIZE) @Schema(defaultValue = "25") @Min(1) @Max(200) Integer pageSize, - @CanBeLogged - @Parameter(description = "Offset used for pagination") + @Parameter(description = "Offset used for pagination") @BindParam(value = PAGE_NUMBER) @Schema(defaultValue = "0") @Min(0) diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsResponse.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsResponse.java index 002a9eb5065dcbdaf776e02214e54c11d8c86c33..33fe86d64e4e4ad4ca5920279f010825bd20db2f 100644 --- a/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsResponse.java +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GetAvailableAuditLogsResponse.java @@ -5,14 +5,12 @@ package de.eshg.auditlog; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import java.util.List; public record GetAvailableAuditLogsResponse( - @CanBeLogged @NotNull @Schema(description = "Total number of result pages") int totalPages, - @CanBeLogged @NotNull @Schema(description = "Total number of result elements") - long totalElements, - @NotNull @Valid List<AuditLogGrantedAccessDto> logs) {} + @NotNull @Schema(description = "Total number of result pages") int totalPages, + @NotNull @Schema(description = "Total number of result elements") long totalElements, + @NotNull @Valid List<AuditLogGrantedAccessCountDto> logs) {} diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/GrantedAccessDto.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GrantedAccessDto.java new file mode 100644 index 0000000000000000000000000000000000000000..eba50f3b8d66ba90c5def8c5a34749217d935363 --- /dev/null +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/GrantedAccessDto.java @@ -0,0 +1,14 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.auditlog; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; +import java.util.UUID; + +@Schema(name = "GrantedAccess") +public record GrantedAccessDto(@NotNull UUID idOfGrantedUser, @NotNull Instant expiresAt) {} diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/SharedAuditLogTestHelperApi.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/SharedAuditLogTestHelperApi.java new file mode 100644 index 0000000000000000000000000000000000000000..ecb62e274c5387693abfab38e0cbd59eb6aec839 --- /dev/null +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/SharedAuditLogTestHelperApi.java @@ -0,0 +1,25 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.auditlog; + +import static de.eshg.auditlog.SharedAuditLogTestHelperApi.BASE_URL; + +import java.io.IOException; +import org.springframework.web.service.annotation.DeleteExchange; +import org.springframework.web.service.annotation.HttpExchange; +import org.springframework.web.service.annotation.PostExchange; + +@HttpExchange(BASE_URL) +public interface SharedAuditLogTestHelperApi { + + String BASE_URL = "/test-helper"; + + @DeleteExchange("audit-log-storage") + void clearAuditLogStorageDirectory() throws IOException; + + @PostExchange("archiving-job") + void runArchivingJob(); +} diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/feature/AuditLogFeature.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/feature/AuditLogFeature.java new file mode 100644 index 0000000000000000000000000000000000000000..75d9e7af5dc2296e332123b9fd25479cd9ad2494 --- /dev/null +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/feature/AuditLogFeature.java @@ -0,0 +1,10 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.auditlog.feature; + +public enum AuditLogFeature { + AUDIT_LOG_ACCESSIBLE_TABLE +} diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/feature/AuditLogFeatureTogglesApi.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/feature/AuditLogFeatureTogglesApi.java new file mode 100644 index 0000000000000000000000000000000000000000..186e2b08bb3d9a149820e68c1dd363a5bb440e4c --- /dev/null +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/feature/AuditLogFeatureTogglesApi.java @@ -0,0 +1,18 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.auditlog.feature; + +import de.eshg.rest.service.security.config.BaseUrls.AuditLog; +import org.springframework.web.service.annotation.GetExchange; +import org.springframework.web.service.annotation.HttpExchange; + +@HttpExchange(value = AuditLogFeatureTogglesApi.BASE_URL) +public interface AuditLogFeatureTogglesApi { + String BASE_URL = AuditLog.FEATURE_TOGGLES_CONTROLLER; + + @GetExchange + GetAuditLogFeatureTogglesResponse getFeatureToggles(); +} diff --git a/backend/auditlog-api/src/main/java/de/eshg/auditlog/feature/GetAuditLogFeatureTogglesResponse.java b/backend/auditlog-api/src/main/java/de/eshg/auditlog/feature/GetAuditLogFeatureTogglesResponse.java new file mode 100644 index 0000000000000000000000000000000000000000..cb7a92c9d0e57b299f49c6037745c5436e380026 --- /dev/null +++ b/backend/auditlog-api/src/main/java/de/eshg/auditlog/feature/GetAuditLogFeatureTogglesResponse.java @@ -0,0 +1,13 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.auditlog.feature; + +import jakarta.validation.constraints.NotNull; +import java.util.Set; + +public record GetAuditLogFeatureTogglesResponse( + @NotNull Set<AuditLogFeature> enabledNewFeatures, + @NotNull Set<AuditLogFeature> disabledOldFeatures) {} diff --git a/backend/auditlog/gradle.lockfile b/backend/auditlog/gradle.lockfile index c57ee9b49f873962c657fc8829d5dce1da6780e3..c77d2d932b241a73d0a8ab5649edba867d28dac3 100644 --- a/backend/auditlog/gradle.lockfile +++ b/backend/auditlog/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -40,8 +41,8 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -49,11 +50,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -61,14 +62,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -92,10 +92,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -112,8 +112,8 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -139,7 +139,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -147,30 +147,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -180,19 +180,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath diff --git a/backend/auditlog/openApi.yaml b/backend/auditlog/openApi.yaml index 96c345bc26f446c535cde2099a0db3c30bea5c6c..fcc47e4011e8123cc0cf1c958b3f4871e4e52a25 100644 --- a/backend/auditlog/openApi.yaml +++ b/backend/auditlog/openApi.yaml @@ -146,6 +146,30 @@ paths: tags: - AuditLog /auditlog/grant-access: + get: + operationId: getAuditLogGrantedAccesses + parameters: + - in: query + name: source + required: true + schema: + $ref: "#/components/schemas/AuditLogSource" + - in: query + name: date + required: true + schema: + type: string + format: date + responses: + "200": + content: + '*/*': + schema: + $ref: "#/components/schemas/GetAuditLogGrantedAccessesResponse" + description: OK + summary: List all granted accesses of audit log. + tags: + - AuditLog post: operationId: grantAuditLogAccess requestBody: @@ -161,9 +185,9 @@ paths: a certain user. tags: - AuditLog - /auditlog/grantees: + /auditlog/grantees-candidates: get: - operationId: getValidAuditLogGrantees + operationId: getAuditLogGranteesCandidates parameters: - in: query name: source @@ -211,6 +235,18 @@ paths: summary: Get user specific asymmetrically encrypted symmetric key. tags: - AuditLog + /feature-toggles: + get: + operationId: getFeatureToggles + responses: + "200": + content: + '*/*': + schema: + $ref: "#/components/schemas/GetAuditLogFeatureTogglesResponse" + description: OK + tags: + - AuditLogFeatureToggles /test-helper/archiving-job: post: operationId: runArchivingJob @@ -218,7 +254,7 @@ paths: "200": description: OK tags: - - AuditLogTestHelper + - TestHelper /test-helper/audit-log-storage: delete: operationId: clearAuditLogStorageDirectory @@ -226,7 +262,21 @@ paths: "200": description: OK tags: - - AuditLogTestHelper + - TestHelper + /test-helper/enabled-new-features/{featureToEnable}: + post: + operationId: enableNewFeature + parameters: + - in: path + name: featureToEnable + required: true + schema: + $ref: "#/components/schemas/AuditLogFeature" + responses: + "200": + description: OK + tags: + - TestHelper /test-helper/population: post: operationId: populateDefaults @@ -393,7 +443,11 @@ components: required: - date - source - AuditLogGrantedAccessDto: + AuditLogFeature: + type: string + enum: + - AUDIT_LOG_ACCESSIBLE_TABLE + AuditLogGrantedAccessCount: type: object properties: auditLog: @@ -432,13 +486,43 @@ components: $ref: "#/components/schemas/AccessibleAuditLog" required: - accessibleAuditLogs + GetAuditLogFeatureTogglesResponse: + type: object + properties: + disabledOldFeatures: + type: array + items: + $ref: "#/components/schemas/AuditLogFeature" + uniqueItems: true + enabledNewFeatures: + type: array + items: + $ref: "#/components/schemas/AuditLogFeature" + uniqueItems: true + required: + - disabledOldFeatures + - enabledNewFeatures + GetAuditLogGrantedAccessesResponse: + type: object + properties: + grantedAccesses: + type: array + items: + $ref: "#/components/schemas/GrantedAccess" + resolvedUsers: + type: object + additionalProperties: + $ref: "#/components/schemas/User" + required: + - grantedAccesses + - resolvedUsers GetAvailableAuditLogsResponse: type: object properties: logs: type: array items: - $ref: "#/components/schemas/AuditLogGrantedAccessDto" + $ref: "#/components/schemas/AuditLogGrantedAccessCount" totalElements: type: integer format: int64 @@ -492,6 +576,18 @@ components: - date - idsOfGrantedUser - source + GrantedAccess: + type: object + properties: + expiresAt: + type: string + format: date-time + idOfGrantedUser: + type: string + format: uuid + required: + - expiresAt + - idOfGrantedUser HttpMethod: type: string enum: diff --git a/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogApplication.java b/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogApplication.java index 7b906c82efddedb3c855bd6a520ba9ae60ece1e5..b37872332f4c0e5ca549d1d354c44ae7661c0e98 100644 --- a/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogApplication.java +++ b/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogApplication.java @@ -5,13 +5,14 @@ package de.eshg.auditlog; +import de.eshg.auditlog.feature.AuditLogFeatureToggle; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; @SpringBootApplication -@EnableConfigurationProperties(AuditLogServiceConfig.class) +@EnableConfigurationProperties({AuditLogServiceConfig.class, AuditLogFeatureToggle.class}) public class AuditLogApplication { @Bean diff --git a/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogController.java b/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogController.java index b41cdf07783a1569b80f80ba3e2d69b8fb09f76a..1339f44bc802ccae80eef80383235c423bf950dd 100644 --- a/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogController.java +++ b/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogController.java @@ -5,20 +5,25 @@ package de.eshg.auditlog; +import static de.base.rest.CustomMediaTypes.TEXT_PLAIN_UTF_8; import static de.eshg.auditlog.AuditLogApi.QueryParameter.END_DATE; import static de.eshg.auditlog.AuditLogApi.QueryParameter.START_DATE; import static de.eshg.base.user.api.UserRoleDto.AUDITLOG_DECRYPT_AND_ACCESS; +import de.cronn.commons.lang.StreamUtil; import de.eshg.auditlog.crypto.AsymmetricEncryption; import de.eshg.auditlog.crypto.AsymmetricEncryption.EncryptedKey; import de.eshg.auditlog.crypto.AuditLogDecryptionException; import de.eshg.auditlog.crypto.AuditLogEncryptionException; import de.eshg.auditlog.crypto.SymmetricEncryption; import de.eshg.auditlog.crypto.SymmetricEncryption.EncryptedPayload; +import de.eshg.auditlog.domain.model.AuditLogAccessibleProjection; import de.eshg.auditlog.domain.model.AuditLogGrantedAccessProjection; +import de.eshg.auditlog.domain.model.AuditLogGranteesProjection; import de.eshg.auditlog.domain.model.GrantedAccess; import de.eshg.auditlog.domain.model.GrantedAccessRepository; import de.eshg.base.user.UserApi; +import de.eshg.base.user.api.GetUsersRequest; import de.eshg.base.user.api.GetUsersResponse; import de.eshg.base.user.api.UserDto; import de.eshg.base.user.api.UserFilterParameters; @@ -60,10 +65,14 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.ContentDisposition; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.HttpClientErrorException; @@ -128,7 +137,8 @@ public class AuditLogController implements AuditLogApi, AuditLogArchivingApi { } @Override - public String readAuditLogFile(String key, ReadAuditLogFileRequest readAuditLogFileRequest) { + public ResponseEntity<String> readAuditLogFile( + String key, ReadAuditLogFileRequest readAuditLogFileRequest) { UserDto selfUser = userApi.getSelfUser(); Map<String, String> additionalData = @@ -152,8 +162,14 @@ public class AuditLogController implements AuditLogApi, AuditLogArchivingApi { readAuditLogFileRequest.source(), readAuditLogFileRequest.date(), selfUser); try { - return new String( - decryptAuditLogFile(key, auditLogFilePath, ivFilePath), StandardCharsets.UTF_8); + ContentDisposition contentDisposition = ContentDisposition.inline().build(); + + return ResponseEntity.ok() + .contentType(TEXT_PLAIN_UTF_8) + .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString()) + .body( + new String( + decryptAuditLogFile(key, auditLogFilePath, ivFilePath), StandardCharsets.UTF_8)); } catch (IOException e) { throw new UncheckedIOException("Unable to read audit log files", e); } catch (InvalidKeyException | javax.crypto.AEADBadTagException e) { @@ -164,18 +180,57 @@ public class AuditLogController implements AuditLogApi, AuditLogArchivingApi { } @Override - public GetUsersResponse getValidAuditLogGrantees( - GetValidAuditLogGranteesRequest getValidAuditLogGranteesRequest) { - AuditLogSource source = getValidAuditLogGranteesRequest.source(); - LocalDate date = getValidAuditLogGranteesRequest.date(); + public GetUsersResponse getAuditLogGranteesCandidates( + GetAuditLogDataRequest getAuditLogDataRequest) { + AuditLogSource source = getAuditLogDataRequest.source(); + LocalDate date = getAuditLogDataRequest.date(); List<UserDto> users = userApi.getUsers(new UserFilterParameters(AUDITLOG_DECRYPT_AND_ACCESS, null)).users(); - List<UserDto> validGrantees = + List<UserDto> granteesCandidates = users.stream().filter(user -> existsUserSpecificDir(user.userId(), source, date)).toList(); - return new GetUsersResponse(validGrantees); + return new GetUsersResponse(granteesCandidates); + } + + @Override + public GetAuditLogGrantedAccessesResponse getAuditLogGrantedAccesses( + GetAuditLogDataRequest getAuditLogDataRequest) { + AuditLogSource source = getAuditLogDataRequest.source(); + LocalDate date = getAuditLogDataRequest.date(); + + List<AuditLogGranteesProjection> grantees = + grantedAccessRepository.findByAuditLogAndExpiresAtIsAfter(date, source, Instant.now(clock)); + + Map<UUID, UserDto> resolvedUsers = resolveUsers(grantees); + + List<GrantedAccessDto> grantedAccesses = + grantees.stream() + .sorted(Comparator.comparing(user -> resolveUserLastName(user, resolvedUsers))) + .map( + grantee -> + new GrantedAccessDto(grantee.getIdOfGrantedUser(), grantee.getExpiresAt())) + .toList(); + + return new GetAuditLogGrantedAccessesResponse(grantedAccesses, resolvedUsers); + } + + private Map<UUID, UserDto> resolveUsers(List<AuditLogGranteesProjection> grantees) { + return userApi.getUsersBulk(new GetUsersRequest(getUserIds(grantees), false)).users().stream() + .sorted(Comparator.comparing(UserDto::lastName)) + .collect(StreamUtil.toLinkedHashMap(UserDto::userId, Function.identity())); + } + + private String resolveUserLastName( + AuditLogGranteesProjection user, Map<UUID, UserDto> resolvedUsers) { + return resolvedUsers.get(user.getIdOfGrantedUser()).lastName(); + } + + private Set<UUID> getUserIds(List<AuditLogGranteesProjection> grantedAccessProjection) { + return grantedAccessProjection.stream() + .map(AuditLogGranteesProjection::getIdOfGrantedUser) + .collect(Collectors.toCollection(LinkedHashSet::new)); } private Optional<String> getRequestRemoteAddress() { @@ -311,7 +366,7 @@ public class AuditLogController implements AuditLogApi, AuditLogArchivingApi { .limit(paginationOptions.pageSize()) .toList(); - List<AuditLogGrantedAccessDto> enrichedAuditLogs = new ArrayList<>(); + List<AuditLogGrantedAccessCountDto> enrichedAuditLogs = new ArrayList<>(); List<AuditLogGrantedAccessProjection> grantedAccessProjection = grantedAccessRepository.findByAuditLogInAndExpiresAtIsAfter( @@ -321,7 +376,7 @@ public class AuditLogController implements AuditLogApi, AuditLogArchivingApi { for (AuditLogDto auditLog : truncatedAuditLogs) { int validGrantedAccessCount = getValidGrantedAccessCount(auditLog, grantedAccessProjection); - enrichedAuditLogs.add(new AuditLogGrantedAccessDto(auditLog, validGrantedAccessCount)); + enrichedAuditLogs.add(new AuditLogGrantedAccessCountDto(auditLog, validGrantedAccessCount)); } return new GetAvailableAuditLogsResponse( @@ -417,7 +472,8 @@ public class AuditLogController implements AuditLogApi, AuditLogArchivingApi { @Override public GetAccessibleAuditLogsResponse getAccessibleAuditLogs() { UserDto selfUser = userApi.getSelfUser(); - List<GrantedAccess> accesses = + + List<AuditLogAccessibleProjection> accesses = grantedAccessRepository.findByIdOfGrantedUserAndExpiresAtIsAfter( selfUser.userId(), Instant.now(clock)); return new GetAccessibleAuditLogsResponse( @@ -697,7 +753,8 @@ public class AuditLogController implements AuditLogApi, AuditLogArchivingApi { return new AuditLogDto(date, source); } - private AccessibleAuditLogDto mapToAccessibleAuditLogDto(GrantedAccess grantedAccess) { + private AccessibleAuditLogDto mapToAccessibleAuditLogDto( + AuditLogAccessibleProjection grantedAccess) { return new AccessibleAuditLogDto( new AuditLogDto(grantedAccess.getDate(), grantedAccess.getAuditLogSource()), grantedAccess.getExpiresAt()); diff --git a/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogTestHelperController.java b/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogTestHelperController.java index 0ceeb1133043fdd4b04f4342d6be00b33e06527f..77418d3611bfedd0d99cb4e6a35a3d81c43b5cff 100644 --- a/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogTestHelperController.java +++ b/backend/auditlog/src/main/java/de/eshg/auditlog/AuditLogTestHelperController.java @@ -5,6 +5,8 @@ package de.eshg.auditlog; +import de.eshg.auditlog.feature.AuditLogFeature; +import de.eshg.auditlog.feature.AuditLogFeatureToggle; import de.eshg.lib.auditlog.AuditLogArchiving; import de.eshg.lib.auditlog.AuditLogTestHelperService; import de.eshg.testhelper.ConditionalOnTestHelperEnabled; @@ -18,7 +20,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController @ConditionalOnTestHelperEnabled -@Tag(name = "AuditLogTestHelper") +@Tag(name = "TestHelper") public class AuditLogTestHelperController implements AuditLogTestHelperApi { private static final Logger log = LoggerFactory.getLogger(AuditLogTestHelperController.class); @@ -26,14 +28,17 @@ public class AuditLogTestHelperController implements AuditLogTestHelperApi { private final AuditLogArchiving auditLogArchiving; private final AuditLogServiceConfig auditLogServiceConfig; private final AuditLogTestHelperService auditLogTestHelperService; + private final AuditLogFeatureToggle auditLogFeatureToggle; public AuditLogTestHelperController( AuditLogArchiving auditLogArchiving, AuditLogServiceConfig auditLogServiceConfig, - AuditLogTestHelperService auditLogTestHelperService) { + AuditLogTestHelperService auditLogTestHelperService, + AuditLogFeatureToggle auditLogFeatureToggle) { this.auditLogArchiving = auditLogArchiving; this.auditLogServiceConfig = auditLogServiceConfig; this.auditLogTestHelperService = auditLogTestHelperService; + this.auditLogFeatureToggle = auditLogFeatureToggle; } @Override @@ -49,4 +54,9 @@ public class AuditLogTestHelperController implements AuditLogTestHelperApi { public void runArchivingJob() { auditLogArchiving.runArchivingJob(); } + + @Override + public void enableNewFeature(AuditLogFeature featureToEnable) { + auditLogFeatureToggle.enableNewFeature(featureToEnable); + } } diff --git a/backend/auditlog/src/main/java/de/eshg/auditlog/domain/model/AuditLogAccessibleProjection.java b/backend/auditlog/src/main/java/de/eshg/auditlog/domain/model/AuditLogAccessibleProjection.java new file mode 100644 index 0000000000000000000000000000000000000000..17147ab90d12c0596eda971d5a7afe5f12e6ba1c --- /dev/null +++ b/backend/auditlog/src/main/java/de/eshg/auditlog/domain/model/AuditLogAccessibleProjection.java @@ -0,0 +1,22 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.auditlog.domain.model; + +import de.eshg.auditlog.AuditLogSource; +import java.time.Instant; +import java.time.LocalDate; +import java.util.UUID; + +public interface AuditLogAccessibleProjection { + + LocalDate getDate(); + + AuditLogSource getAuditLogSource(); + + Instant getExpiresAt(); + + UUID getIdOfGrantedUser(); +} diff --git a/backend/auditlog/src/main/java/de/eshg/auditlog/domain/model/AuditLogGranteesProjection.java b/backend/auditlog/src/main/java/de/eshg/auditlog/domain/model/AuditLogGranteesProjection.java new file mode 100644 index 0000000000000000000000000000000000000000..357edae549163ad676fd7663337230a9db51d346 --- /dev/null +++ b/backend/auditlog/src/main/java/de/eshg/auditlog/domain/model/AuditLogGranteesProjection.java @@ -0,0 +1,15 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.auditlog.domain.model; + +import java.time.Instant; +import java.util.UUID; + +public interface AuditLogGranteesProjection { + UUID getIdOfGrantedUser(); + + Instant getExpiresAt(); +} diff --git a/backend/auditlog/src/main/java/de/eshg/auditlog/domain/model/GrantedAccessRepository.java b/backend/auditlog/src/main/java/de/eshg/auditlog/domain/model/GrantedAccessRepository.java index 37ae41ae5aba4a2fb872ddfac8bf573ea1d29da5..417830db3a7cf261280f2f3e2cf61e13ccd15727 100644 --- a/backend/auditlog/src/main/java/de/eshg/auditlog/domain/model/GrantedAccessRepository.java +++ b/backend/auditlog/src/main/java/de/eshg/auditlog/domain/model/GrantedAccessRepository.java @@ -23,7 +23,15 @@ public interface GrantedAccessRepository extends JpaRepository<GrantedAccess, Lo Optional<GrantedAccess> findByAuditLogSourceAndDateAndIdOfGrantedUserAndExpiresAtIsAfter( AuditLogSource auditLogSource, LocalDate date, UUID idOfGrantedUser, Instant now); - List<GrantedAccess> findByIdOfGrantedUserAndExpiresAtIsAfter(UUID idOfGrantedUser, Instant now); + @Query( + """ + SELECT date as date, auditLogSource as auditLogSource, idOfGrantedUser as idOfGrantedUser, max(expiresAt) as expiresAt + FROM GrantedAccess g + WHERE expiresAt > :now + AND idOfGrantedUser = :idOfGrantedUser + GROUP BY (date, auditLogSource, idOfGrantedUser)""") + List<AuditLogAccessibleProjection> findByIdOfGrantedUserAndExpiresAtIsAfter( + @Param("idOfGrantedUser") UUID idOfGrantedUser, @Param("now") Instant now); @Transactional(readOnly = true) boolean existsByAuditLogSourceAndDateAndExpiresAtIsAfter( @@ -40,7 +48,20 @@ public interface GrantedAccessRepository extends JpaRepository<GrantedAccess, Lo List<AuditLogGrantedAccessProjection> findByAuditLogInAndExpiresAtIsAfter( @Param("dates") Set<LocalDate> dates, @Param("sources") Set<AuditLogSource> sources, - Instant now); + @Param("now") Instant now); + + @Query( + """ + SELECT idOfGrantedUser as idOfGrantedUser, max(expiresAt) as expiresAt + FROM GrantedAccess g + WHERE expiresAt > :now + AND date = :date + AND auditLogSource = :source + GROUP BY idOfGrantedUser""") + List<AuditLogGranteesProjection> findByAuditLogAndExpiresAtIsAfter( + @Param("date") LocalDate date, + @Param("source") AuditLogSource source, + @Param("now") Instant now); @Transactional @Modifying diff --git a/backend/auditlog/src/main/java/de/eshg/auditlog/feature/AuditLogFeatureToggle.java b/backend/auditlog/src/main/java/de/eshg/auditlog/feature/AuditLogFeatureToggle.java new file mode 100644 index 0000000000000000000000000000000000000000..8c390e2ef87155c0216125e9432b6aa2d7d666c5 --- /dev/null +++ b/backend/auditlog/src/main/java/de/eshg/auditlog/feature/AuditLogFeatureToggle.java @@ -0,0 +1,14 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.auditlog.feature; + +import de.eshg.testhelper.FeatureToggle; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +@Validated +@ConfigurationProperties(prefix = "de.eshg.auditlog.feature-toggle", ignoreUnknownFields = false) +public class AuditLogFeatureToggle extends FeatureToggle<AuditLogFeature> {} diff --git a/backend/auditlog/src/main/java/de/eshg/auditlog/feature/AuditLogFeatureTogglesController.java b/backend/auditlog/src/main/java/de/eshg/auditlog/feature/AuditLogFeatureTogglesController.java new file mode 100644 index 0000000000000000000000000000000000000000..3cae6dc0db50b98c4787d16a37a473c58ac93c99 --- /dev/null +++ b/backend/auditlog/src/main/java/de/eshg/auditlog/feature/AuditLogFeatureTogglesController.java @@ -0,0 +1,26 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.auditlog.feature; + +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@Tag(name = "AuditLogFeatureToggles") +public class AuditLogFeatureTogglesController implements AuditLogFeatureTogglesApi { + private final AuditLogFeatureToggle auditLogFeatureToggle; + + public AuditLogFeatureTogglesController(AuditLogFeatureToggle auditLogFeatureToggle) { + this.auditLogFeatureToggle = auditLogFeatureToggle; + } + + @Override + public GetAuditLogFeatureTogglesResponse getFeatureToggles() { + return new GetAuditLogFeatureTogglesResponse( + auditLogFeatureToggle.getEnabledNewFeatures(), + auditLogFeatureToggle.getDisabledOldFeatures()); + } +} diff --git a/backend/auditlog/src/main/resources/application-preview-features.properties b/backend/auditlog/src/main/resources/application-preview-features.properties new file mode 100644 index 0000000000000000000000000000000000000000..754692e467b73d11fd1649bd7e398df812a72466 --- /dev/null +++ b/backend/auditlog/src/main/resources/application-preview-features.properties @@ -0,0 +1 @@ +de.eshg.base.feature-toggle.enabled-new-features=AUDIT_LOG_ACCESSIBLE_TABLE diff --git a/backend/auth/gradle.lockfile b/backend/auth/gradle.lockfile index c2e5e8c91a6e6190091e0c4f9da213b259614252..316affa439aa2fa02d9da4f2c0d8f32ac3c37738 100644 --- a/backend/auth/gradle.lockfile +++ b/backend/auth/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,9 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath,testCompileClasspath +com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -39,34 +39,33 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath io.lettuce:lettuce-core:6.3.2.RELEASE=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-buffer:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-common:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-handler:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-resolver:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-transport-native-unix-common:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-transport:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.projectreactor:reactor-core:3.6.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-buffer:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-common:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-handler:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport-native-unix-common:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.projectreactor:reactor-core:3.6.10=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -87,10 +86,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath @@ -106,7 +105,7 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -131,34 +130,34 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=compileClasspath,jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.reactivestreams:reactive-streams:1.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-redis:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-keyvalue:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-redis:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-redis:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-keyvalue:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-redis:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -169,18 +168,18 @@ org.springframework.security:spring-security-oauth2-resource-server:6.3.3=produc org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.session:spring-session-core:3.3.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.session:spring-session-data-redis:3.3.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context-support:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-oxm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context-support:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-oxm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.19.8=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath diff --git a/backend/auth/src/main/java/de/eshg/security/auth/AuthProperties.java b/backend/auth/src/main/java/de/eshg/security/auth/AuthProperties.java index 6a8f0f853890a606de42f1ad6c12c9570109771b..3c128bebdef69d1368ac8224a64bd752ddb3a3f7 100644 --- a/backend/auth/src/main/java/de/eshg/security/auth/AuthProperties.java +++ b/backend/auth/src/main/java/de/eshg/security/auth/AuthProperties.java @@ -26,11 +26,11 @@ public record AuthProperties( private static final Logger log = LoggerFactory.getLogger(AuthProperties.class); public AuthProperties { - if (getAccessCodeUrlPatterns() != null) { - log.info("Access code URL patterns: {}", getAccessCodeUrlPatterns()); + if (auth.accessCodeUrlPatterns() != null) { + log.info("Access code URL patterns: {}", auth.accessCodeUrlPatterns()); } - if (getMukUrlPatterns() != null) { - log.info("MUK URL patterns: {}", getMukUrlPatterns()); + if (auth.mukUrlPatterns() != null) { + log.info("MUK URL patterns: {}", auth.mukUrlPatterns()); } } @@ -48,7 +48,15 @@ public record AuthProperties( return auth().mukUrlPatterns(); } + public List<String> getLanguagePathPrefixes() { + if (auth() == null) { + return null; + } + return auth().languagePathPrefixes(); + } + record Auth( + List<String> languagePathPrefixes, List<String> accessCodeUrlPatterns, List<String> mukUrlPatterns, @Valid UserAgentFilter userAgentFilter) {} diff --git a/backend/auth/src/main/java/de/eshg/security/auth/login/LoginMethod.java b/backend/auth/src/main/java/de/eshg/security/auth/login/LoginMethod.java index 55e0cd1f46378ddc07b78d4517394b9dd7d19ea8..831b82d30456b4dedba46d6acd4f2530043caa5e 100644 --- a/backend/auth/src/main/java/de/eshg/security/auth/login/LoginMethod.java +++ b/backend/auth/src/main/java/de/eshg/security/auth/login/LoginMethod.java @@ -37,7 +37,21 @@ public abstract class LoginMethod { return false; } String urlPath = UriComponentsBuilder.fromUriString(url).build().getPath(); - return urlPath != null - && patterns.stream().anyMatch(pattern -> antPathMatcher.match(pattern, urlPath)); + String normalizedUrlPath = replaceLanguagePathPrefix(urlPath); + return normalizedUrlPath != null + && patterns.stream().anyMatch(pattern -> antPathMatcher.match(pattern, normalizedUrlPath)); + } + + private String replaceLanguagePathPrefix(String url) { + List<String> languagePathPrefixes = authProperties.getLanguagePathPrefixes(); + if (languagePathPrefixes == null) { + return url; + } + for (String languagePathPrefix : languagePathPrefixes) { + if (url.startsWith(languagePathPrefix + "/")) { + return url.substring(languagePathPrefix.length()); + } + } + return url; } } diff --git a/backend/auth/src/main/resources/application-citizen-portal.properties b/backend/auth/src/main/resources/application-citizen-portal.properties index 53d90342bbb7771ac5340029ed6b1cad565f4e6e..e399424338028272c71d10edee7cdac3faafccb0 100644 --- a/backend/auth/src/main/resources/application-citizen-portal.properties +++ b/backend/auth/src/main/resources/application-citizen-portal.properties @@ -4,5 +4,6 @@ eshg.reverse-proxy.url=http://localhost:4001 spring.security.oauth2.client.registration.keycloak.client-secret=tstj3RgLtqF4Kbh3hVNRRXTwxLkhmq +eshg.auth.language-path-prefixes=/de, /en eshg.auth.access-code-url-patterns=/einschulungsuntersuchung/termin, /impfberatung/meine-termine eshg.auth.muk-url-patterns=/unternehmen/** diff --git a/backend/base-api/gradle.lockfile b/backend/base-api/gradle.lockfile index 5cdf2844ddfd353f8246cb3de124efc04c6ef92e..a4830c624a98c68d0d0a9fda4beb0c0d364e3c33 100644 --- a/backend/base-api/gradle.lockfile +++ b/backend/base-api/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -11,9 +11,9 @@ com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2=compileClasspath,p com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -54,21 +54,21 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesAnnotationProcessor diff --git a/backend/base-api/src/main/java/de/eshg/base/centralfile/PersonApi.java b/backend/base-api/src/main/java/de/eshg/base/centralfile/PersonApi.java index 7cf76432a29a190d765d2933f97dde3ca5d92c8a..51e15c665fae2592529cc142704b3d18298005a5 100644 --- a/backend/base-api/src/main/java/de/eshg/base/centralfile/PersonApi.java +++ b/backend/base-api/src/main/java/de/eshg/base/centralfile/PersonApi.java @@ -114,7 +114,7 @@ public interface PersonApi { If no reference person matches the mandatory parameters of the new file state, a new reference person is created. Non-mandatory parameters are ignored when searching for matching reference persons. """) - GetPersonFileStatesResponse addPersonFileStates( + AddPersonFileStatesResponse addPersonFileStates( @Parameter(description = "A list of Persons that shall be added to the Central Files.") @RequestBody @Valid diff --git a/backend/base-api/src/main/java/de/eshg/base/centralfile/api/facility/AddFacilityFileStateRequest.java b/backend/base-api/src/main/java/de/eshg/base/centralfile/api/facility/AddFacilityFileStateRequest.java index b72a9fb295c97d2facb551247b2ed2ef1460ee7c..59946302f6466cfd205cf45c7d62f2a31a1ef58d 100644 --- a/backend/base-api/src/main/java/de/eshg/base/centralfile/api/facility/AddFacilityFileStateRequest.java +++ b/backend/base-api/src/main/java/de/eshg/base/centralfile/api/facility/AddFacilityFileStateRequest.java @@ -65,6 +65,20 @@ public record AddFacilityFileStateRequest( partialMatch); } + public AddFacilityFileStateRequest( + UUID referenceFacilityId, FacilityDetailsDto facilityDetails, DataOriginDto dataOrigin) { + this( + referenceFacilityId, + facilityDetails.name(), + facilityDetails.emailAddresses(), + facilityDetails.phoneNumbers(), + facilityDetails.contactPersons(), + facilityDetails.contactAddress(), + facilityDetails.differentBillingAddress(), + dataOrigin, + null); + } + public AddFacilityFileStateRequest( String name, List<String> emailAddresses, diff --git a/backend/base-api/src/main/java/de/eshg/base/centralfile/api/person/AddPersonFileStatesResponse.java b/backend/base-api/src/main/java/de/eshg/base/centralfile/api/person/AddPersonFileStatesResponse.java new file mode 100644 index 0000000000000000000000000000000000000000..b871a337984a2d64e2a43a44049df2de07eac54c --- /dev/null +++ b/backend/base-api/src/main/java/de/eshg/base/centralfile/api/person/AddPersonFileStatesResponse.java @@ -0,0 +1,19 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.base.centralfile.api.person; + +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import java.util.UUID; + +public record AddPersonFileStatesResponse( + @ArraySchema( + arraySchema = + @Schema(description = "A list containing the file state IDs of the added persons")) + @NotNull + List<UUID> personFileStateIds) {} diff --git a/backend/base-api/src/main/java/de/eshg/base/contact/api/ContactFilterParameters.java b/backend/base-api/src/main/java/de/eshg/base/contact/api/ContactFilterParameters.java index 8327a5c7213e04f469239358a74855985b4a0264..8ea9ccf9613693f61d03503b9b91b0abacf99c5a 100644 --- a/backend/base-api/src/main/java/de/eshg/base/contact/api/ContactFilterParameters.java +++ b/backend/base-api/src/main/java/de/eshg/base/contact/api/ContactFilterParameters.java @@ -14,12 +14,8 @@ import jakarta.validation.constraints.Min; public record ContactFilterParameters( @Parameter( description = - "The last name of the Contact (or parts of it) which shall be searched for.") + "The full name of the Contact (or parts of it) which shall be searched for.") String name, - @Parameter( - description = - "The first name(s) of the Contact (or parts of it) which shall be searched for.") - String firstName, @Parameter( description = "The street, as the main part of the address of a Contact, (or parts of it) which shall be searched for.") diff --git a/backend/base-api/src/main/java/de/eshg/base/department/DepartmentApi.java b/backend/base-api/src/main/java/de/eshg/base/department/DepartmentApi.java index b7842e0195482008ee98312c9dd52e5b918a8384..b02abd800525a1f01602584b29c34f5177469825 100644 --- a/backend/base-api/src/main/java/de/eshg/base/department/DepartmentApi.java +++ b/backend/base-api/src/main/java/de/eshg/base/department/DepartmentApi.java @@ -8,6 +8,7 @@ package de.eshg.base.department; import static de.eshg.rest.service.security.config.BaseUrls.Base.DEPARTMENT_API_INFO; import static de.eshg.rest.service.security.config.BaseUrls.Base.DEPARTMENT_API_LOGO; import static de.eshg.rest.service.security.config.BaseUrls.Base.DEPARTMENT_API_SECURITY_TXT; +import static de.eshg.rest.service.security.config.BaseUrls.Base.DEPARTMENT_API_SECURITY_TXT_PGP_KEY; import de.eshg.rest.service.security.config.BaseUrls; import io.swagger.v3.oas.annotations.Operation; @@ -35,4 +36,11 @@ public interface DepartmentApi { @ApiResponse(responseCode = "200") @Operation(summary = "Get the security.txt file of the department running this application.") ResponseEntity<byte[]> getSecurityTxt(); + + @GetExchange(DEPARTMENT_API_SECURITY_TXT_PGP_KEY) + @ApiResponse(responseCode = "200") + @Operation( + summary = + "Get the security.txt public PGP key file of the department running this application.") + ResponseEntity<byte[]> getSecurityTxtPublicKey(); } diff --git a/backend/base/gradle.lockfile b/backend/base/gradle.lockfile index 42acec3e287c4f1bfeb3343d97fbf255a6eb128a..0b3698b3c76856b1922c2819ec15f742c4cf4d2b 100644 --- a/backend/base/gradle.lockfile +++ b/backend/base/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -31,9 +31,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath,testCompileClasspath +com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.googlecode.ez-vcard:ez-vcard:0.12.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -64,7 +64,7 @@ commons-codec:commons-codec:1.16.1=compileClasspath,productionRuntimeClasspath,r commons-collections:commons-collections:3.2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.11.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-logging:commons-logging:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -73,30 +73,29 @@ de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,test de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath io.github.java-diff-utils:java-diff-utils:4.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.quarkus:quarkus-junit4-mock:3.14.4=testCompileClasspath,testRuntimeClasspath +io.quarkus:quarkus-junit4-mock:3.15.0=testCompileClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger:swagger-annotations:1.6.14=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.mail:jakarta.mail-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.ws.rs:jakarta.ws.rs-api:3.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -131,10 +130,10 @@ org.apache.james:apache-mime4j-dom:0.8.9=compileClasspath,productionRuntimeClass org.apache.james:apache-mime4j-storage:0.8.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.ws.xmlschema:xmlschema-core:2.3.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -162,9 +161,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -193,9 +192,9 @@ org.junit.platform:junit-platform-commons:1.10.3=testCompileClasspath,testRuntim org.junit.platform:junit-platform-engine:1.10.3=testRuntimeClasspath org.junit.platform:junit-platform-launcher:1.10.3=testRuntimeClasspath org.junit:junit-bom:5.10.3=testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-admin-client:25.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-common:25.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-core:25.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.keycloak:keycloak-admin-client:25.0.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.keycloak:keycloak-common:25.0.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.keycloak:keycloak-core:25.0.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.latencyutils:LatencyUtils:2.0.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.liquibase:liquibase-core:4.27.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.mnode.ical4j:ical4j:4.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -207,7 +206,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.reactivestreams:reactive-streams:1.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath @@ -216,32 +215,32 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-mail:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-thymeleaf:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-mail:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-thymeleaf:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -251,20 +250,20 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context-support:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context-support:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/base/openApi.yaml b/backend/base/openApi.yaml index 3156cc8ea45e6c7c51ef1041611a3f1c6e3b9c81..3412a8b50131b9091faa3417ac405cc0eb42f8a1 100644 --- a/backend/base/openApi.yaml +++ b/backend/base/openApi.yaml @@ -498,20 +498,13 @@ paths: get: operationId: getContacts parameters: - - description: The last name of the Contact (or parts of it) which shall be + - description: The full name of the Contact (or parts of it) which shall be searched for. in: query name: name required: false schema: type: string - - description: The first name(s) of the Contact (or parts of it) which shall - be searched for. - in: query - name: firstName - required: false - schema: - type: string - description: "The street, as the main part of the address of a Contact, (or\ \ parts of it) which shall be searched for." in: query @@ -866,6 +859,21 @@ paths: summary: Get the security.txt file of the department running this application. tags: - Department + /department/security-txt-public-key: + get: + operationId: getSecurityTxtPublicKey + responses: + "200": + content: + '*/*': + schema: + type: string + format: byte + description: OK + summary: Get the security.txt public PGP key file of the department running + this application. + tags: + - Department /facilities: get: operationId: searchReferenceFacilities @@ -1891,7 +1899,7 @@ paths: content: '*/*': schema: - $ref: "#/components/schemas/GetPersonFileStatesResponse" + $ref: "#/components/schemas/AddPersonFileStatesResponse" description: OK summary: | Add multiple persons and associate each with a reference person. @@ -3835,6 +3843,17 @@ components: minItems: 1 required: - persons + AddPersonFileStatesResponse: + type: object + properties: + personFileStateIds: + type: array + description: A list containing the file state IDs of the added persons + items: + type: string + format: uuid + required: + - personFileStateIds AddResourceRequest: type: object properties: @@ -7734,6 +7753,9 @@ components: $ref: "#/components/schemas/TaskStatus" taskType: $ref: "#/components/schemas/TaskType" + version: + type: integer + format: int64 required: - businessModule - createdAt @@ -7744,6 +7766,7 @@ components: - taskId - taskStatus - taskType + - version TaskDueAtReminderNotification: type: object allOf: diff --git a/backend/base/src/main/java/de/eshg/base/centralfile/FacilityController.java b/backend/base/src/main/java/de/eshg/base/centralfile/FacilityController.java index 4bb6265d3b3886949d7af8cb8f455757c435f32e..62da7cf225b1b5882007d6cf76bc164f1f9f3c89 100644 --- a/backend/base/src/main/java/de/eshg/base/centralfile/FacilityController.java +++ b/backend/base/src/main/java/de/eshg/base/centralfile/FacilityController.java @@ -17,9 +17,9 @@ import de.eshg.base.centralfile.persistence.repository.FacilityRepository; import de.eshg.base.centralfile.persistence.repository.FacilitySearchSpecification; import de.eshg.base.feature.BaseFeature; import de.eshg.base.feature.BaseFeatureToggle; +import de.eshg.base.util.FuzzySearchHelper; import de.eshg.rest.service.error.NotFoundException; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.persistence.EntityManager; import java.time.Clock; import java.time.Duration; import java.time.Instant; @@ -37,23 +37,20 @@ public class FacilityController implements FacilityApi { private final FacilityRepository facilityRepository; private final FacilityService facilityService; - private final FacilityMapper facilityMapper; private final BaseFeatureToggle featureToggle; - private final EntityManager entityManager; + private final FuzzySearchHelper fuzzySearchHelper; private final Clock clock; public FacilityController( FacilityRepository facilityRepository, FacilityService facilityService, - FacilityMapper facilityMapper, BaseFeatureToggle featureToggle, - EntityManager entityManager, + FuzzySearchHelper fuzzySearchHelper, Clock clock) { this.facilityRepository = facilityRepository; this.facilityService = facilityService; - this.facilityMapper = facilityMapper; this.featureToggle = featureToggle; - this.entityManager = entityManager; + this.fuzzySearchHelper = fuzzySearchHelper; this.clock = clock; } @@ -90,7 +87,7 @@ public class FacilityController implements FacilityApi { @Override @Transactional(readOnly = true) public SearchReferenceFacilitiesResponse searchReferenceFacilities(String name) { - configureSimilarityThreshold(name); + fuzzySearchHelper.setSimilarityThreshold(getSimilarityThreshold(name)); FacilitySearchSpecification spec = new FacilitySearchSpecification(name); List<GetReferenceFacilityResponse> facilities = @@ -101,13 +98,6 @@ public class FacilityController implements FacilityApi { return new SearchReferenceFacilitiesResponse(facilities); } - private void configureSimilarityThreshold(String name) { - double threshold = getSimilarityThreshold(name); - entityManager - .createNativeQuery("set local pg_trgm.similarity_threshold=" + threshold) - .executeUpdate(); - } - @Override @Transactional(readOnly = true) public GetFileStateIdsResponse getFacilityFileStateIdsWithSameReferenceFacility(UUID id) { @@ -120,6 +110,7 @@ public class FacilityController implements FacilityApi { } @Override + @Transactional(readOnly = true) public GetFileStateIdsResponse getFacilityFileStateIdsAssociatedWithReferenceFacility( UUID referenceId) { Facility referenceFacility = diff --git a/backend/base/src/main/java/de/eshg/base/centralfile/PersonController.java b/backend/base/src/main/java/de/eshg/base/centralfile/PersonController.java index 611379b7785faca6e55daa9bb947c5a658e762ce..54a5b8e1bfd13e6ed4cb889ce6d244040b9116fd 100644 --- a/backend/base/src/main/java/de/eshg/base/centralfile/PersonController.java +++ b/backend/base/src/main/java/de/eshg/base/centralfile/PersonController.java @@ -69,15 +69,13 @@ public class PersonController implements PersonApi { @Override @Transactional - public GetPersonFileStatesResponse addPersonFileStates(AddPersonFileStatesRequest request) { + public AddPersonFileStatesResponse addPersonFileStates(AddPersonFileStatesRequest request) { List<Person> personsToAdd = request.persons().stream().map(PersonMapper::mapPersonToDm).toList(); - List<Person> savedPersonFileStates = personService.addPersonFileStates(personsToAdd); + List<UUID> personFileStateIds = personService.addPersonFileStates(personsToAdd); - return new GetPersonFileStatesResponse( - savedPersonFileStates.stream().map(PersonMapper::mapPersonFileStateToApi).toList(), - List.of()); + return new AddPersonFileStatesResponse(personFileStateIds); } @Override diff --git a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/FacilityService.java b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/FacilityService.java index 642f5020ce05bf7479d13e197eea1efab4b74e43..87e2cc27b0d0fb1382b227c3b3af2e330cc44d05 100644 --- a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/FacilityService.java +++ b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/FacilityService.java @@ -130,10 +130,6 @@ public class FacilityService { public static boolean isFacilityFileStateOutdated( Facility facilityFileState, Facility referenceFacility) { - Long referenceVersion = facilityFileState.getReferenceVersion(); - if (referenceVersion != null && referenceVersion >= referenceFacility.getVersion()) { - return false; - } return !FacilityMatcher.isFacilityMatch(referenceFacility, facilityFileState); } @@ -187,8 +183,8 @@ public class FacilityService { .findReferenceFacilityByFileStateExternalId(facilityFileState.getExternalId()) .orElseThrow(() -> new NotFoundException("Associated Reference Facility not found")); - if (facilityFileState.getReferenceVersion() < referenceFacility.getVersion()) { - throw new BadRequestException(ErrorCode.CONFLICT, "Version mismatch, file state is outdated"); + if (isFacilityFileStateOutdated(facilityFileState, referenceFacility)) { + throw new BadRequestException(ErrorCode.CONFLICT, "Facility file state is outdated"); } if (findMatchingReferenceFacility(fileStateUpdate).isPresent()) { @@ -216,6 +212,11 @@ public class FacilityService { ValidationUtil.validateVersion(version, referenceFacility); + if (!isFacilityFileStateOutdated(facilityFileState, referenceFacility)) { + throw new BadRequestException( + ErrorCode.CONFLICT, "File state and associated reference facility already match"); + } + Facility updatedFileState = referenceFacility.cloneFromReferenceFacility(); updatedFileState.setDataOrigin(DataOrigin.EDIT); return addFacilityFileState(updatedFileState, referenceFacility); diff --git a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/PersonService.java b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/PersonService.java index 093efb83b95bd0e074c22dd4050c90d67f7b2982..adf77d0714774beb16ff31237c8619e011de363c 100644 --- a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/PersonService.java +++ b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/PersonService.java @@ -15,6 +15,7 @@ import de.eshg.base.centralfile.persistence.entity.DataOrigin; import de.eshg.base.centralfile.persistence.entity.Person; import de.eshg.base.centralfile.persistence.entity.Person_; import de.eshg.base.centralfile.persistence.repository.PersonRepository; +import de.eshg.base.util.FuzzySearchHelper; import de.eshg.base.util.PersonDiffer; import de.eshg.mutex.MutexService; import de.eshg.rest.service.error.AlreadyExistsException; @@ -22,7 +23,6 @@ import de.eshg.rest.service.error.BadRequestException; import de.eshg.rest.service.error.ErrorCode; import de.eshg.rest.service.error.NotFoundException; import de.eshg.validation.ValidationUtil; -import jakarta.persistence.EntityManager; import jakarta.persistence.criteria.JoinType; import jakarta.persistence.criteria.Predicate; import java.time.Clock; @@ -40,7 +40,7 @@ public class PersonService { public static final String MUTEX_PERSON_WRITE = "PERSON_WRITE"; private final PersonRepository personRepository; - private final EntityManager entityManager; + private final FuzzySearchHelper fuzzySearchHelper; private final MutexService mutexService; private final CentralFileAuditLogger logger; private final Clock clock; @@ -48,21 +48,17 @@ public class PersonService { public PersonService( PersonRepository personRepository, MutexService mutexService, - EntityManager entityManager, + FuzzySearchHelper fuzzySearchHelper, CentralFileAuditLogger logger, Clock clock) { this.personRepository = personRepository; this.mutexService = mutexService; - this.entityManager = entityManager; + this.fuzzySearchHelper = fuzzySearchHelper; this.logger = logger; this.clock = clock; } public static boolean isPersonFileStateOutdated(Person personFileState, Person referencePerson) { - Long referenceVersion = personFileState.getReferenceVersion(); - if (referenceVersion != null && referenceVersion >= referencePerson.getVersion()) { - return false; - } return !PersonDiffer.isPersonMatch(personFileState, referencePerson); } @@ -104,13 +100,12 @@ public class PersonService { return savedPersonFileState; } - public List<Person> addPersonFileStates(List<Person> personsToAdd) { + public List<UUID> addPersonFileStates(List<Person> personsToAdd) { return mutexService.doWithLockedMutex( MUTEX_PERSON_WRITE, () -> addPersonFileStatesWhenLocked(personsToAdd)); } - private List<Person> addPersonFileStatesWhenLocked(List<Person> fileStates) { - + private List<UUID> addPersonFileStatesWhenLocked(List<Person> fileStates) { Set<PersonKeyAttributes> personKeyAttributes = collectPersonKeyAttributes(fileStates); List<Person> potentialMatches = findAllByKeyAttributes(personKeyAttributes); @@ -125,7 +120,9 @@ public class PersonService { logger.logAddFileState(fileState); } - return personRepository.saveAll(fileStates); + personRepository.saveAll(fileStates); + + return fileStates.stream().map(Person::getExternalId).toList(); } private static void prepareFileStateToAddToDb(Person fileState, Person referencePerson) { @@ -170,9 +167,7 @@ public class PersonService { private void configureSimilarityThreshold(String firstName, String lastName) { double threshold = Math.min(getSimilarityThreshold(firstName), getSimilarityThreshold(lastName)); - entityManager - .createNativeQuery("set local pg_trgm.similarity_threshold=" + threshold) - .executeUpdate(); + fuzzySearchHelper.setSimilarityThreshold(threshold); } public Optional<Person> findMatchingReferencePerson(Person person) { @@ -242,8 +237,8 @@ public class PersonService { .findReferencePersonByFileStateId(personFileState.getExternalId()) .orElseThrow(() -> new NotFoundException("Associated Reference Person not found")); - if (!Objects.equals(personFileState.getReferenceVersion(), referencePerson.getVersion())) { - throw new BadRequestException(ErrorCode.CONFLICT, "Version mismatch, file state is outdated"); + if (isPersonFileStateOutdated(personFileState, referencePerson)) { + throw new BadRequestException(ErrorCode.CONFLICT, "Person file state is outdated"); } if (findMatchingReferencePerson(fileStateUpdate).isPresent()) { @@ -272,6 +267,11 @@ public class PersonService { ValidationUtil.validateVersion(version, referencePerson); + if (!isPersonFileStateOutdated(personFileState, referencePerson)) { + throw new BadRequestException( + ErrorCode.CONFLICT, "File state and associated reference person already match"); + } + Person updatedFileState = referencePerson.cloneFromReferencePerson(); updatedFileState.setDataOrigin(DataOrigin.EDIT); return addPersonFileState(updatedFileState, referencePerson); diff --git a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/Person.java b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/Person.java index f172042b4777deeaff0bfc05200bbd700986217f..330f4fd5d7aa76e622194c9345ed83407f75d14b 100644 --- a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/Person.java +++ b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/Person.java @@ -10,7 +10,7 @@ import de.eshg.base.address.persistence.entity.Address; import de.eshg.base.centralfile.CentralFileData; import de.eshg.base.util.Gender; import de.eshg.base.util.Salutation; -import de.eshg.domain.model.BaseEntityWithExternalId; +import de.eshg.domain.model.SequencedBaseEntityWithExternalId; import de.eshg.lib.common.DataSensitivity; import de.eshg.lib.common.SensitivityLevel; import jakarta.persistence.*; @@ -29,7 +29,7 @@ import org.hibernate.dialect.PostgreSQLEnumJdbcType; @Index(columnList = "reference_person_id"), @Index(columnList = "first_name, last_name, date_of_birth"), }) -public class Person extends BaseEntityWithExternalId implements CentralFileData { +public class Person extends SequencedBaseEntityWithExternalId implements CentralFileData { @DataSensitivity(SensitivityLevel.PROTECTED) private Instant modifiedAt; diff --git a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonAddress.java b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonAddress.java index fe9cd90e1e47bd050f022ad8901d737a22bc6cc5..590d1252d33d9c63557da010f70ec7e61570b210 100644 --- a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonAddress.java +++ b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonAddress.java @@ -6,11 +6,11 @@ package de.eshg.base.centralfile.persistence.entity; import de.eshg.base.address.persistence.entity.Address; -import de.eshg.domain.model.BaseEntity; +import de.eshg.domain.model.SequencedBaseEntity; import jakarta.persistence.Entity; import jakarta.persistence.Inheritance; import jakarta.persistence.InheritanceType; @Entity @Inheritance(strategy = InheritanceType.JOINED) -public abstract class PersonAddress extends BaseEntity implements Address {} +public abstract class PersonAddress extends SequencedBaseEntity implements Address {} diff --git a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonEmailAddress.java b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonEmailAddress.java index 3147eaafc7013795d1981b2b168e207219c92576..7aafbc64dc541a4fabf0f5e024b100e72f141d08 100644 --- a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonEmailAddress.java +++ b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonEmailAddress.java @@ -5,7 +5,7 @@ package de.eshg.base.centralfile.persistence.entity; -import de.eshg.domain.model.BaseEntity; +import de.eshg.domain.model.SequencedBaseEntity; import de.eshg.lib.common.DataSensitivity; import de.eshg.lib.common.SensitivityLevel; import jakarta.persistence.Column; @@ -17,7 +17,7 @@ import jakarta.persistence.Table; @Entity @Table(indexes = @Index(columnList = PersonEmailAddress.PERSON_ID)) -public class PersonEmailAddress extends BaseEntity { +public class PersonEmailAddress extends SequencedBaseEntity { static final String PERSON_ID = "person_id"; diff --git a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonPhoneNumber.java b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonPhoneNumber.java index d8f3e02c2cb914713a9628e483201e3297e61720..0b8945420b65cbf32bbde7079c4b2fa4f93b9a0f 100644 --- a/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonPhoneNumber.java +++ b/backend/base/src/main/java/de/eshg/base/centralfile/persistence/entity/PersonPhoneNumber.java @@ -5,7 +5,7 @@ package de.eshg.base.centralfile.persistence.entity; -import de.eshg.domain.model.BaseEntity; +import de.eshg.domain.model.SequencedBaseEntity; import de.eshg.lib.common.DataSensitivity; import de.eshg.lib.common.SensitivityLevel; import jakarta.persistence.Column; @@ -17,7 +17,7 @@ import jakarta.persistence.Table; @Entity @Table(indexes = @Index(columnList = PersonPhoneNumber.PERSON_ID)) -public class PersonPhoneNumber extends BaseEntity { +public class PersonPhoneNumber extends SequencedBaseEntity { public static final String PERSON_ID = "person_id"; diff --git a/backend/base/src/main/java/de/eshg/base/contact/ContactController.java b/backend/base/src/main/java/de/eshg/base/contact/ContactController.java index ae6bccb66dbd4aaa4ee0567bee18ec7b8dcfceef..56bfa7adb5b8be22dd153901d6269d167d7c0a05 100644 --- a/backend/base/src/main/java/de/eshg/base/contact/ContactController.java +++ b/backend/base/src/main/java/de/eshg/base/contact/ContactController.java @@ -205,10 +205,10 @@ public class ContactController implements ContactApi { }; InstitutionContactCategory institutionContactCategory = ContactMapper.mapInstitutionContactCategoryToDm(parameters.category()); + Page<? extends Contact> contacts = contactService.fuzzySearchContacts( parameters.name(), - parameters.firstName(), parameters.street(), contactType, institutionContactCategory, diff --git a/backend/base/src/main/java/de/eshg/base/contact/persistence/ContactSearchSpecificationUtil.java b/backend/base/src/main/java/de/eshg/base/contact/persistence/ContactSearchSpecificationUtil.java index 2af6567eee383b650f65eb2b95b4ad60938bc1e6..17ef82b86c952d421413bf29092552df149ef5ca 100644 --- a/backend/base/src/main/java/de/eshg/base/contact/persistence/ContactSearchSpecificationUtil.java +++ b/backend/base/src/main/java/de/eshg/base/contact/persistence/ContactSearchSpecificationUtil.java @@ -14,6 +14,7 @@ import de.eshg.base.contact.ContactMapper; import de.eshg.base.contact.api.ContactSortKey; import de.eshg.base.contact.persistence.entity.*; import de.eshg.base.util.PaginationUtil; +import de.eshg.base.util.SearchSpecificationUtil; import jakarta.persistence.criteria.*; import jakarta.persistence.metamodel.SingularAttribute; import org.springframework.data.domain.Sort; @@ -41,19 +42,10 @@ public class ContactSearchSpecificationUtil { }; } - static Specification<Contact> orderBySimilarity(String name, String firstName, String street) { + static Specification<Contact> orderBySimilarity(String name, String street) { return (root, query, cb) -> { - Expression<Double> orderExpression = similarity(cb, name, root.get(Contact_.name)); - if (firstName != null) { - orderExpression = - cb.sum( - orderExpression, - similarity( - cb, - firstName, - cb.treat(root, PersonContact.class).get(PersonContact_.firstName))); - } + Expression<Double> orderExpression = similarity(cb, name, getFullNameExpression(root, cb)); if (street != null) { orderExpression = cb.sum( @@ -112,16 +104,17 @@ public class ContactSearchSpecificationUtil { static Specification<Contact> containsNameOrHasFuzzy(String name) { return (root, query, cb) -> { - Path<String> field = root.get(Contact_.name); - return containsStringFieldOrHasFuzzy(cb, name, field); + Expression<String> fullName = getFullNameExpression(root, cb); + return containsStringFieldOrHasFuzzy(cb, name, fullName); }; } - static Specification<Contact> containsFirstNameOrHasFuzzy(String firstName) { - return (root, query, cb) -> { - Path<String> field = cb.treat(root, PersonContact.class).get(PersonContact_.firstName); - return containsStringFieldOrHasFuzzy(cb, firstName, field); - }; + private static Expression<String> getFullNameExpression(Root<Contact> root, CriteriaBuilder cb) { + Path<String> namePath = root.get(Contact_.name); + Path<String> firstNamePath = cb.treat(root, PersonContact.class).get(PersonContact_.firstName); + Expression<String> fullName = + SearchSpecificationUtil.concatWithSeparator(cb, firstNamePath, namePath); + return fullName; } static Specification<Contact> containsStreetOrHasFuzzy(String street) { @@ -132,7 +125,7 @@ public class ContactSearchSpecificationUtil { } private static Predicate containsStringFieldOrHasFuzzy( - CriteriaBuilder cb, String value, Path<String> field) { + CriteriaBuilder cb, String value, Expression<String> field) { if (value == null || value.isEmpty()) { return cb.and(); } diff --git a/backend/base/src/main/java/de/eshg/base/contact/persistence/ContactService.java b/backend/base/src/main/java/de/eshg/base/contact/persistence/ContactService.java index 254aee91d97b216d891537515ab06e37b03cec37..c8bd1ad6057f4447dad51eff28dc2237d5e2850f 100644 --- a/backend/base/src/main/java/de/eshg/base/contact/persistence/ContactService.java +++ b/backend/base/src/main/java/de/eshg/base/contact/persistence/ContactService.java @@ -30,6 +30,7 @@ import de.eshg.base.contact.persistence.entity.InstitutionContactCategory; import de.eshg.base.contact.persistence.entity.PersonContact; import de.eshg.base.contact.persistence.entity.PostboxContactAddress; import de.eshg.base.contact.persistence.repository.ContactRepository; +import de.eshg.base.util.FuzzySearchHelper; import de.eshg.base.util.MappingUtil; import de.eshg.base.util.PaginationUtil.PageSpec; import de.eshg.domain.model.BaseRevisionEntity_; @@ -40,6 +41,7 @@ import de.eshg.mapper.RevisionEntryWithChange; import de.eshg.rest.service.security.CurrentUserHelper; import jakarta.persistence.EntityManager; import jakarta.persistence.LockModeType; +import jakarta.persistence.PersistenceContext; import jakarta.persistence.metamodel.SingularAttribute; import java.time.Instant; import java.util.ArrayList; @@ -74,13 +76,16 @@ public class ContactService { private final ContactRepository contactRepository; private final AuditLogger auditLogger; - private final EntityManager entityManager; + private final FuzzySearchHelper fuzzySearchHelper; + @PersistenceContext private EntityManager entityManager; public ContactService( - ContactRepository contactRepository, AuditLogger auditLogger, EntityManager entityManager) { + ContactRepository contactRepository, + AuditLogger auditLogger, + FuzzySearchHelper fuzzySearchHelper) { this.contactRepository = contactRepository; this.auditLogger = auditLogger; - this.entityManager = entityManager; + this.fuzzySearchHelper = fuzzySearchHelper; } public Optional<Contact> findById(UUID id) { @@ -350,37 +355,31 @@ public class ContactService { public <T extends Contact> Page<T> fuzzySearchContacts( String name, - String firstName, String street, Class<T> type, InstitutionContactCategory category, PageSpec pageSpec) { + fuzzySearchHelper.setSimilarityThreshold(0.2); Specification<Contact> specification = Specification.allOf( isNotMergedInto(), containsNameOrHasFuzzy(name), - containsFirstNameOrHasFuzzy(firstName), containsStreetOrHasFuzzy(street), hasCategory(category)); if (!type.equals(Contact.class)) { specification = Specification.allOf(specification, hasType(type)); } - return fuzzySortAndPage(name, firstName, street, pageSpec, specification).map(type::cast); + return fuzzySortAndPage(name, street, pageSpec, specification).map(type::cast); } private Page<Contact> fuzzySortAndPage( - String name, - String firstname, - String street, - PageSpec pageSpec, - Specification<Contact> specification) { + String name, String street, PageSpec pageSpec, Specification<Contact> specification) { String sortKey = pageSpec.order().getProperty(); SingularAttribute<Contact, String> fallbackSortKey = Contact_.name; switch (sortKey) { case RELEVANCE_SORT_KEY -> { - specification = - Specification.allOf(specification, orderBySimilarity(name, firstname, street)); + specification = Specification.allOf(specification, orderBySimilarity(name, street)); return contactRepository.findAll( specification, PageRequest.of(pageSpec.pageNumber(), pageSpec.pageSize())); } @@ -429,7 +428,6 @@ public class ContactService { return fuzzySearchContacts( vCardData.fullName(), - null, vCardData.addresses().getFirst().street(), InstitutionContact.class, null, @@ -441,13 +439,12 @@ public class ContactService { return Page.empty(); } - return fuzzySearchContacts( - vCardData.lastName(), - vCardData.firstName(), - null, - PersonContact.class, - null, - getPageSpec()); + String fullName = + vCardData.firstName() != null + ? vCardData.firstName() + " " + vCardData.lastName() + : vCardData.lastName(); + + return fuzzySearchContacts(fullName, null, PersonContact.class, null, getPageSpec()); } private void writeAuditLog(String operationName, Map<String, String> attributes) { diff --git a/backend/base/src/main/java/de/eshg/base/department/DepartmentConfiguration.java b/backend/base/src/main/java/de/eshg/base/department/DepartmentConfiguration.java index c7b6ef933c99190b18a8cc2e0a6f57f69ba05d40..894da3011135d9bb19f260a787682c1a7f4cad46 100644 --- a/backend/base/src/main/java/de/eshg/base/department/DepartmentConfiguration.java +++ b/backend/base/src/main/java/de/eshg/base/department/DepartmentConfiguration.java @@ -30,6 +30,7 @@ public record DepartmentConfiguration( @NotNull Double longitude, @NotNull Resource logo, @NotNull Resource securityTxt, + @NotNull Resource securityTxtPublicKey, @NotNull Resource streetDirectory, @NotNull Resource municipalityDirectory) { @@ -48,6 +49,7 @@ public record DepartmentConfiguration( @NotNull Double longitude, @NotNull Resource logo, @NotNull Resource securityTxt, + @NotNull Resource securityTxtPublicKey, @NotNull Resource streetDirectory, @NotNull Resource municipalityDirectory) { this.name = name; @@ -63,12 +65,14 @@ public record DepartmentConfiguration( this.latitude = latitude; this.longitude = longitude; this.securityTxt = securityTxt; + this.securityTxtPublicKey = securityTxtPublicKey; this.logo = logo; this.streetDirectory = streetDirectory; this.municipalityDirectory = municipalityDirectory; assertIsReadable(logo, "Department logo"); assertIsReadable(securityTxt, "Department security txt"); + assertIsReadable(securityTxtPublicKey, "Department security txt public key"); assertIsReadable(streetDirectory, "Department street directory"); assertIsReadable(municipalityDirectory, "Department municipality directory"); } diff --git a/backend/base/src/main/java/de/eshg/base/department/DepartmentController.java b/backend/base/src/main/java/de/eshg/base/department/DepartmentController.java index 2adaf421b14a2da74d1957991bc8092db18cf2e5..5105a7dd379f0cdf62b59c6a7c2abff872e56ff1 100644 --- a/backend/base/src/main/java/de/eshg/base/department/DepartmentController.java +++ b/backend/base/src/main/java/de/eshg/base/department/DepartmentController.java @@ -47,6 +47,16 @@ public class DepartmentController implements DepartmentApi { } } + @Override + public ResponseEntity<byte[]> getSecurityTxtPublicKey() { + try { + byte[] securityTxt = departmentConfiguration.securityTxtPublicKey().getContentAsByteArray(); + return ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN).body(securityTxt); + } catch (IOException e) { + throw new RuntimeException("Could not read security txt public key file.", e); + } + } + private GetDepartmentInfoResponse mapToResponse(DepartmentConfiguration departmentConfig) { return new GetDepartmentInfoResponse( departmentConfig.name(), diff --git a/backend/base/src/main/java/de/eshg/base/inventory/persistence/InventoryService.java b/backend/base/src/main/java/de/eshg/base/inventory/persistence/InventoryService.java index b0f8a34637a2fcb99cf80400b2879f8721438a1d..0de50d8f3672f44351b6bcd21c3622aebd0e0029 100644 --- a/backend/base/src/main/java/de/eshg/base/inventory/persistence/InventoryService.java +++ b/backend/base/src/main/java/de/eshg/base/inventory/persistence/InventoryService.java @@ -17,6 +17,7 @@ import de.eshg.base.inventory.persistence.repository.InventoryRepository; import de.eshg.base.label.persistence.LabelService; import de.eshg.base.label.persistence.entity.Label; import de.eshg.base.label.persistence.entity.Label_; +import de.eshg.base.util.FuzzySearchHelper; import de.eshg.base.util.PaginationUtil.PageSpec; import de.eshg.lib.auditlog.AuditLogger; import de.eshg.lib.keycloak.EmployeePermissionRole; @@ -27,6 +28,7 @@ import de.eshg.rest.service.security.CurrentUserHelper; import de.eshg.validation.ValidationUtil; import jakarta.persistence.EntityManager; import jakarta.persistence.LockModeType; +import jakarta.persistence.PersistenceContext; import jakarta.ws.rs.NotFoundException; import java.util.*; import org.springframework.data.domain.Page; @@ -45,19 +47,21 @@ public class InventoryService { private final InventoryRepository inventoryRepository; private final InventoryBookingRepository inventoryBookingRepository; - private final EntityManager entityManager; + private final FuzzySearchHelper fuzzySearchHelper; private final LabelService labelService; private final AuditLogger auditLogger; + @PersistenceContext private EntityManager entityManager; + public InventoryService( InventoryRepository inventoryRepository, InventoryBookingRepository inventoryBookingRepository, - EntityManager entityManager, + FuzzySearchHelper fuzzySearchHelper, LabelService labelService, AuditLogger auditLogger) { this.inventoryRepository = inventoryRepository; this.inventoryBookingRepository = inventoryBookingRepository; - this.entityManager = entityManager; + this.fuzzySearchHelper = fuzzySearchHelper; this.labelService = labelService; this.auditLogger = auditLogger; } @@ -66,7 +70,7 @@ public class InventoryService { if (name == null || name.isEmpty()) { return (root, query, builder) -> builder.and(); } - configureSimilarityThreshold(name); + fuzzySearchHelper.setSimilarityThreshold(getSimilarityThreshold(name)); return (root, query, builder) -> builder.or( containsNormalized(builder, root.get(InventoryItem_.name), splitToWords(name)), @@ -74,13 +78,6 @@ public class InventoryService { isSimilar(builder, builder.literal(name), root.get(InventoryItem_.name)))); } - private void configureSimilarityThreshold(String name) { - double threshold = getSimilarityThreshold(name); - entityManager - .createNativeQuery("set local pg_trgm.similarity_threshold=" + threshold) - .executeUpdate(); - } - private static Specification<InventoryItem> hasType(InventoryItemType type) { if (type == null) { return (root, query, builder) -> builder.and(); diff --git a/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakMapper.java b/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakMapper.java index 17f37005c7c94f391ba8fe9652bbaf39c0384c9d..1d6fae333dc1b3cb5a4acbc42b21624288270929 100644 --- a/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakMapper.java +++ b/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakMapper.java @@ -31,7 +31,6 @@ import org.keycloak.representations.idm.UserRepresentation; import org.springframework.util.CollectionUtils; public class KeycloakMapper { - public static final String KEYCLOAK_SYSTEM_PREFIX = "[System] "; private KeycloakMapper() { throw new UnsupportedOperationException("Util class"); @@ -153,6 +152,8 @@ public class KeycloakMapper { String.valueOf(smtp.port()), "auth", "true", + "ssl", + String.valueOf(smtp.sslEnabled()), "user", smtp.username(), "password", diff --git a/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakProperties.java b/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakProperties.java index a0c720cbeb5fcf310fa85a2cfd5caf5d30959c2f..4f0b110412dd42a63c8684309a2ffa1ee04bb746 100644 --- a/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakProperties.java +++ b/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakProperties.java @@ -200,6 +200,7 @@ public record KeycloakProperties( @NotBlank String from, @NotBlank String host, @NotNull Integer port, + @NotNull Boolean sslEnabled, @NotBlank String username, @NotBlank String password) {} diff --git a/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakProvisioning.java b/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakProvisioning.java index 4a5a600998fbdac992e74290daa8cd28350d2363..f47cddcf0e78d41b8268c1684d90b7364d00815e 100644 --- a/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakProvisioning.java +++ b/backend/base/src/main/java/de/eshg/base/keycloak/KeycloakProvisioning.java @@ -32,7 +32,9 @@ public abstract class KeycloakProvisioning<T extends RealmBoundKeycloakClient> { public static final List<String> WEBAUTHN_SIGNATURE_ALGORITHMS = List.of("Ed25519", "ES256", "RS256"); - public static final String LENIENT_PASSWORD_POLICY = "length(1)"; + // Using weak hash algorithm for test users to speed up credential resets + public static final String TEST_USER_PASSWORD_POLICY = + "length(1) and hashAlgorithm(pbkdf2-sha256) and hashIterations(1)"; public static final String DISABLE_PASSWORD_POLICY = "maxLength(0)"; public static final String ESHG_AUTH_SERVICE_CLIENT_ID = @@ -100,7 +102,7 @@ public abstract class KeycloakProvisioning<T extends RealmBoundKeycloakClient> { realmRepresentation.setSupportedLocales(new LinkedHashSet<>(List.of("de", "en"))); if (this.keycloakProperties.provisionTestUsers()) { log.warn("Using lenient password policy"); - realmRepresentation.setPasswordPolicy(LENIENT_PASSWORD_POLICY); + realmRepresentation.setPasswordPolicy(TEST_USER_PASSWORD_POLICY); } realmRepresentation.setDefaultLocale("de"); realmRepresentation.setLoginTheme("custom-keycloak"); diff --git a/backend/base/src/main/java/de/eshg/base/keycloak/differ/Differ.java b/backend/base/src/main/java/de/eshg/base/keycloak/differ/Differ.java index 4b3069c11bb1e7239e14518d02fc8d8424672db9..50ca652ad6e461c99bce184948ed4028a8abc372 100644 --- a/backend/base/src/main/java/de/eshg/base/keycloak/differ/Differ.java +++ b/backend/base/src/main/java/de/eshg/base/keycloak/differ/Differ.java @@ -15,6 +15,8 @@ import java.util.stream.Collectors; public final class Differ { + private static final List<String> MASKED_JSON_KEYS = List.of("password", "secret"); + private Differ() { throw new IllegalStateException("Utility class"); } @@ -35,10 +37,10 @@ public final class Differ { List<String> diffLines = new ArrayList<>(); for (int i = 0; i < Math.max(sourceLines.size(), targetLines.size()); i++) { if (sourceLines.size() > i) { - diffLines.add("- " + sourceLines.get(i)); + diffLines.add("- " + maskSensitiveData(sourceLines.get(i))); } if (targetLines.size() > i) { - diffLines.add("+ " + targetLines.get(i)); + diffLines.add("+ " + maskSensitiveData(targetLines.get(i))); } } return String.join("\n", diffLines); @@ -47,4 +49,14 @@ public final class Differ { private static List<String> splitLines(String oldString) { return Arrays.stream(oldString.split("\n")).toList(); } + + private static String maskSensitiveData(String line) { + for (String maskedKey : MASKED_JSON_KEYS) { + String quotedMaskedKey = "\"%s\"".formatted(maskedKey); + if (line.trim().startsWith(quotedMaskedKey)) { + return quotedMaskedKey + " : \"[masked]\""; + } + } + return line; + } } diff --git a/backend/base/src/main/java/de/eshg/base/resource/persistence/ResourceService.java b/backend/base/src/main/java/de/eshg/base/resource/persistence/ResourceService.java index 1ef5ac89876e5a75c266fb3302061c8b2fc60f93..af0e69adcd57724963dbbd998db31b3d9cd2088e 100644 --- a/backend/base/src/main/java/de/eshg/base/resource/persistence/ResourceService.java +++ b/backend/base/src/main/java/de/eshg/base/resource/persistence/ResourceService.java @@ -18,12 +18,12 @@ import de.eshg.base.resource.persistence.entity.Resource; import de.eshg.base.resource.persistence.entity.ResourceType; import de.eshg.base.resource.persistence.entity.Resource_; import de.eshg.base.resource.persistence.repository.ResourceRepository; +import de.eshg.base.util.FuzzySearchHelper; import de.eshg.base.util.PaginationUtil.PageSpec; import de.eshg.lib.auditlog.AuditLogger; import de.eshg.rest.service.error.AlreadyExistsException; import de.eshg.rest.service.error.NotFoundException; import de.eshg.rest.service.security.CurrentUserHelper; -import jakarta.persistence.EntityManager; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -44,18 +44,18 @@ public class ResourceService { private final ResourceRepository resourceRepository; private final LabelService labelService; private final CalendarService calendarService; - private final EntityManager entityManager; + private final FuzzySearchHelper fuzzySearchHelper; private final AuditLogger auditLogger; public ResourceService( ResourceRepository resourceRepository, LabelService labelService, CalendarService calendarService, - EntityManager entityManager, + FuzzySearchHelper fuzzySearchHelper, AuditLogger auditLogger) { this.resourceRepository = resourceRepository; this.calendarService = calendarService; - this.entityManager = entityManager; + this.fuzzySearchHelper = fuzzySearchHelper; this.auditLogger = auditLogger; this.labelService = labelService; } @@ -71,7 +71,7 @@ public class ResourceService { if (name == null || name.isEmpty()) { return (root, query, builder) -> builder.and(); } - configureSimilarityThreshold(name); + fuzzySearchHelper.setSimilarityThreshold(getSimilarityThreshold(name)); return (root, query, builder) -> builder.or( containsNormalized(builder, root.get(Resource_.name), splitToWords(name)), @@ -86,13 +86,6 @@ public class ResourceService { builder.equal(root.join(Resource_.labels).get(Label_.name), label); } - private void configureSimilarityThreshold(String name) { - double threshold = getSimilarityThreshold(name); - entityManager - .createNativeQuery("set local pg_trgm.similarity_threshold=" + threshold) - .executeUpdate(); - } - public Page<Resource> findAll( String name, ResourceType resourceType, String label, PageSpec pageSpec) { Specification<Resource> specification = diff --git a/backend/base/src/main/java/de/eshg/base/testhelper/BaseTestHelperController.java b/backend/base/src/main/java/de/eshg/base/testhelper/BaseTestHelperController.java index b84507af2eb1d8fc9445ada7ef6ec88ec627bb48..9d29ab62e2450ba7dd6d1a1dba59141835cb2ab2 100644 --- a/backend/base/src/main/java/de/eshg/base/testhelper/BaseTestHelperController.java +++ b/backend/base/src/main/java/de/eshg/base/testhelper/BaseTestHelperController.java @@ -5,7 +5,7 @@ package de.eshg.base.testhelper; -import de.eshg.auditlog.AuditLogTestHelperApi; +import de.eshg.auditlog.SharedAuditLogTestHelperApi; import de.eshg.base.contact.api.SearchContactsResponse; import de.eshg.base.feature.BaseFeature; import de.eshg.base.feature.BaseFeatureToggle; @@ -35,7 +35,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController @ConditionalOnTestHelperEnabled public class BaseTestHelperController extends TestHelperController - implements BaseTestHelperApi, AuditLogTestHelperApi { + implements BaseTestHelperApi, SharedAuditLogTestHelperApi { private final BaseTestHelperService baseTestHelperService; private final BaseFeatureToggle baseFeatureToggle; diff --git a/backend/base/src/main/java/de/eshg/base/util/FuzzySearchHelper.java b/backend/base/src/main/java/de/eshg/base/util/FuzzySearchHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..2b46fea3f98e446455395a6f025585cf29ba8496 --- /dev/null +++ b/backend/base/src/main/java/de/eshg/base/util/FuzzySearchHelper.java @@ -0,0 +1,33 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.base.util; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class FuzzySearchHelper { + @PersistenceContext private EntityManager entityManager; + + @SuppressWarnings("SqlSourceToSinkFlow") // safe sql string with validated number parameter + @Transactional(propagation = Propagation.MANDATORY) + public void setSimilarityThreshold(double threshold) { + if (!Double.isFinite(threshold)) { + throw new IllegalArgumentException("Threshold must be finite. Provided: " + threshold); + } + if (threshold <= 0 || threshold > 1) { + throw new IllegalArgumentException( + "Threshold must be between 0 and 1. Provided: " + threshold); + } + + entityManager + .createNativeQuery("set local pg_trgm.similarity_threshold=" + threshold) + .executeUpdate(); + } +} diff --git a/backend/base/src/main/java/de/eshg/base/util/SearchSpecificationUtil.java b/backend/base/src/main/java/de/eshg/base/util/SearchSpecificationUtil.java index 2feecd26d3abeae07da58469dc07a18b5ad9f7ee..4b93424a9d17e91a4c149a81ae144cae89cb05bc 100644 --- a/backend/base/src/main/java/de/eshg/base/util/SearchSpecificationUtil.java +++ b/backend/base/src/main/java/de/eshg/base/util/SearchSpecificationUtil.java @@ -7,7 +7,6 @@ package de.eshg.base.util; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Expression; -import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import java.util.*; import org.apache.commons.lang3.StringUtils; @@ -57,11 +56,11 @@ public class SearchSpecificationUtil { } public static Expression<Double> similarity( - CriteriaBuilder builder, String queryWord, Path<String> pathToAttribute) { + CriteriaBuilder builder, String queryWord, Expression<String> expression) { return builder.function( "similarity", Double.class, - normalizeText(builder, pathToAttribute), + normalizeText(builder, expression), normalizeText(builder, builder.literal(queryWord))); } @@ -71,6 +70,13 @@ public class SearchSpecificationUtil { "sql", Boolean.class, cb.literal("? % ?"), normalizeText(cb, lhs), normalizeText(cb, rhs)); } + @SafeVarargs + @SuppressWarnings("varargs") + public static Expression<String> concatWithSeparator( + CriteriaBuilder cb, Expression<String>... expressions) { + return cb.function("immutable_concat_strings_ws", String.class, expressions); + } + /** * The minimum thresholds are computed by taking the trigram similarities of changing a single * symbol in the middle of the word of that length. diff --git a/backend/base/src/main/resources/application-health-department-frankfurt.properties b/backend/base/src/main/resources/application-health-department-frankfurt.properties index cd31cbe40fc1902bce3ba43e77aa07c298403e2d..a46d648f948fc683a7af31bbb0addbf963ba015c 100644 --- a/backend/base/src/main/resources/application-health-department-frankfurt.properties +++ b/backend/base/src/main/resources/application-health-department-frankfurt.properties @@ -12,6 +12,7 @@ eshg.department.latitude=50.114296 eshg.department.longitude=8.691828 eshg.department.logo=classpath:logo-health-department-ffm.svg eshg.department.security-txt=classpath:security-ffm.txt +eshg.department.security-txt-public-key=classpath:security-pgp-key-ffm.txt eshg.department.street-directory=classpath:strassenverzeichnis2022.csv eshg.department.municipality-directory=classpath:municipality-directory-ffm.csv diff --git a/backend/base/src/main/resources/application-preview-features.properties b/backend/base/src/main/resources/application-preview-features.properties index 8274b04996dac6d2344e40714a96cb6d51a7fab3..2ca838691a1ca1f7eda0a2650d42f2604a6c6333 100644 --- a/backend/base/src/main/resources/application-preview-features.properties +++ b/backend/base/src/main/resources/application-preview-features.properties @@ -1 +1 @@ -de.eshg.base.feature-toggle.enabled-new-features=TASK_METRICS, STI_PROTECTION, CHAT_USERNAME, ACCOUNT_ACTIVE_SESSIONS +de.eshg.base.feature-toggle.enabled-new-features=TASK_METRICS, STI_PROTECTION, CHAT_USERNAME, ACCOUNT_ACTIVE_SESSIONS, LOGIN_PROTOCOL, INBOX diff --git a/backend/base/src/main/resources/application.properties b/backend/base/src/main/resources/application.properties index da6f561821a864b0af9c36a7aad9dcc4f4792909..356bc1f58a41a84e5b170614d594702930aad769 100644 --- a/backend/base/src/main/resources/application.properties +++ b/backend/base/src/main/resources/application.properties @@ -6,6 +6,11 @@ spring.datasource.password=testpassword spring.jpa.hibernate.ddl-auto=validate spring.jpa.properties.org.hibernate.envers.store_data_at_delete=true +spring.jpa.properties.hibernate.jdbc.batch_size=100 +spring.jpa.properties.hibernate.order_inserts=true +spring.jpa.properties.hibernate.order_updates=true +spring.jpa.properties.hibernate.batch_versioned_data=true + # Enable explicitly since we disable it by default via common-persistence.properties spring.liquibase.enabled=true spring.liquibase.change-log=classpath:/migrations/changelog.xml @@ -13,10 +18,8 @@ spring.liquibase.change-log=classpath:/migrations/changelog.xml spring.jackson.serialization.indent_output=true spring.mail.host=${DOCKER_HOSTNAME:localhost} spring.mail.port=1025 -spring.mail.properties.mail.smtp.starttls.enable=true -spring.mail.properties.mail.smtp.starttls.required=false -spring.mail.username=${SMTP_USERNAME:testuser} -spring.mail.password=${SMTP_PASSWORD:testpassword} +spring.mail.username=testuser +spring.mail.password=testpassword #Socket connection timeout, implemented by java.net.Socket spring.mail.properties.mail.smtp.connectiontimeout=5000 #Socket read timeout, implemented by java.net.Socket @@ -39,14 +42,13 @@ eshg.keycloak.citizen-realm.muk-idp.encryption-algorithm=RSA-OAEP eshg.keycloak.smtp.from=${eshg.mail.noreply} eshg.keycloak.smtp.host=maildev eshg.keycloak.smtp.port=1025 -eshg.keycloak.smtp.username=${SMTP_USERNAME:testuser} -eshg.keycloak.smtp.password=${SMTP_PASSWORD:testpassword} +eshg.keycloak.smtp.ssl-enabled=false +eshg.keycloak.smtp.username=testuser +eshg.keycloak.smtp.password=testpassword eshg.keycloak.admin.user=admin eshg.keycloak.admin.password=admin eshg.keycloak.admin-client.client-id=ga-lotse-base -eshg.keycloak.setup-admin.email=setup.admin@eshg.de -eshg.keycloak.setup-admin.username=setup.admin -eshg.keycloak.setup-admin.enabled=true +eshg.keycloak.setup-admin.enabled=false eshg.keycloak.event-expiration=90d # Keep this setting in sync with "spring.session.timeout" of the "auth" module # Note that the Keycloak session timeout needs to be higher than the session timeout, because: diff --git a/backend/base/src/main/resources/migrations/0013_person_sequence.xml b/backend/base/src/main/resources/migrations/0013_person_sequence.xml new file mode 100644 index 0000000000000000000000000000000000000000..1d9e611c0d92c0208cdb78e8e7338f99b643b1bc --- /dev/null +++ b/backend/base/src/main/resources/migrations/0013_person_sequence.xml @@ -0,0 +1,17 @@ +<?xml version="1.1" encoding="UTF-8" standalone="no"?> +<!-- + Copyright 2024 cronn GmbH + SPDX-License-Identifier: Apache-2.0 +--> + +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" + xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"> + <changeSet author="GA-Lotse" id="migrate_persons_to_sequence_based_ids"> + <ext:migrateAutoIncrementToSequence tableName="person"/> + <ext:migrateAutoIncrementToSequence tableName="person_address"/> + <ext:migrateAutoIncrementToSequence tableName="person_email_address"/> + <ext:migrateAutoIncrementToSequence tableName="person_phone_number"/> + </changeSet> +</databaseChangeLog> diff --git a/backend/base/src/main/resources/migrations/0014_contact_index_full_name.xml b/backend/base/src/main/resources/migrations/0014_contact_index_full_name.xml new file mode 100644 index 0000000000000000000000000000000000000000..0fc219bf4de70f30fbb145d636e5db2484d1e4ea --- /dev/null +++ b/backend/base/src/main/resources/migrations/0014_contact_index_full_name.xml @@ -0,0 +1,28 @@ +<?xml version="1.1" encoding="UTF-8" standalone="no"?> +<!-- + Copyright 2024 cronn GmbH + SPDX-License-Identifier: Apache-2.0 +--> + +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"> + <changeSet author="GA-Lotse" id="1726999149301-1"> + <sql dbms="postgresql"> + CREATE OR REPLACE FUNCTION immutable_concat_strings_ws(text variadic text[]) + RETURNS text AS + $body$ + select concat_ws(' ', text) + $body$ + LANGUAGE SQL IMMUTABLE; + </sql> + </changeSet> + <changeSet author="GA-Lotse" id="1726999149301-2"> + <sql dbms="postgresql"> + DROP INDEX IF EXISTS trgm_contact_name_idx; + CREATE INDEX trgm_contact_fullname_idx + ON contact + USING gin (normalize_text(immutable_concat_strings_ws(first_name, name)) gin_trgm_ops); + </sql> + </changeSet> +</databaseChangeLog> diff --git a/backend/base/src/main/resources/migrations/changelog.xml b/backend/base/src/main/resources/migrations/changelog.xml index 275b5f049fa19049891b10d0ecb5401580014c3e..511fef83c76894702ff0a930ddbeb35263f106e5 100644 --- a/backend/base/src/main/resources/migrations/changelog.xml +++ b/backend/base/src/main/resources/migrations/changelog.xml @@ -20,5 +20,7 @@ <include file="migrations/0010_remove_and_change_event_type.xml"/> <include file="migrations/0011_change_enum_orders.xml"/> <include file="migrations/0012_rename_single_string_entity_columns.xml"/> + <include file="migrations/0013_person_sequence.xml"/> + <include file="migrations/0014_contact_index_full_name.xml" /> </databaseChangeLog> diff --git a/backend/base/src/main/resources/security-ffm.txt b/backend/base/src/main/resources/security-ffm.txt index 8b137891791fe96927ad78e64b0aad7bded08bdc..d1608c9ef28aa320c82e282df3c7d2e9b76598e1 100644 --- a/backend/base/src/main/resources/security-ffm.txt +++ b/backend/base/src/main/resources/security-ffm.txt @@ -1 +1,26 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 +# For Coordinated Vulnerability Disclosure +Contact: mailto:security@ga-lotse.de +Expires: 2034-12-31T23:00:00.000Z +# Our PGP key for vulnerability disclosure +Encryption: https://ga-lotse.de/pgp-key.txt +Preferred-Languages: de, en +Canonical: https://ga-lotse.de/.well-known/security.txt +-----BEGIN PGP SIGNATURE----- + +iQIzBAEBCgAdFiEEMfoseh5fzKWjiVuI6ztgztlwzNEFAmbz5uwACgkQ6ztgztlw +zNGkow//dQVQVLjt6sK1MxvQzLDWj4YH4DWsVgDfkE9DEAotJO2YJiLRvkiyBed4 +pIDt6zkUpKxzarNWIm87vH8qPKxxv2KDWEJMaEYAJpa0mDVq5haBCYcJBp8cxcQo +pkLZNZ6Lp1/TVkQS29QsusykNI1yq7lF4oNlA5QON2AShvF+xOsbV24FLrbOg1Mx +DUfUdGmgsg3OhNT3rfASPSzek1QsRmWUbFczN+CJo6F/6t9HHMz9BfZAT2vjdv7u +6nAZ56SohRHoVIiGO/7nVvThZeH+guFaJP34q/ZYDkIlLsn8i8Ndp3FxRp42bMCb +0PO+7mTOpBw5HxHKOIwN3Cdgp/jBYJh/CK14D04CGJioBJB7mFgvJ6CioFQT4e5K +Ev54zuhM9cv6jzAQaw85MgAK3sdhq8TkDNpoB3SCnJ4lKn22bMgP74O5wK2vbIzb +7+7ta5UCqks9FS8ixLudCEVJxgEWfVbojX6Au5LJppWjlgJcZHIJrtx/f33rjSeO +XDHrrk8Y4LtehsMQQYiyRUlrDWiFtkspX19N7s4H+T8dxG103oreXWXaQOAqUYkK +MIVQ9kbSap4mG4RNzOYsymbekpkQruwXuNUXV+BekfZOyYs+lmQgCaSPJlmUhvVV +FsXZVGvHGf9HiFhTXWThKJHYigtetnc0QLNjjqv+wRcyLdm0Ls8= +=9mrV +-----END PGP SIGNATURE----- diff --git a/backend/base/src/main/resources/security-pgp-key-ffm.txt b/backend/base/src/main/resources/security-pgp-key-ffm.txt new file mode 100644 index 0000000000000000000000000000000000000000..3cbcce2ce29e7e31da288e3c73bb8672f033d41d --- /dev/null +++ b/backend/base/src/main/resources/security-pgp-key-ffm.txt @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGbxS6gBEADWSJpXvl5iZsXXzf/TfKVrBR9PA5dWTBqZpxjBw/T6/0TR1JG3 +142gQzteHFzOElUnHgw07Z1cSZ/J9N+OJQ70Du2ccvu7BFTBxImHZ/lY8N7/kELo +D/CJhBdRQNOssWFRIrTxsrKGvTf5NvXJb6jXiHkH5t1i78oCIxhWSLlu7P/J/KxZ +O9/BXAEoRi4vISiq4vj764gSCpCZXQy4E+/IGpX86eDjlrGOatOHtkv9e0OAp0sD +kuO6idLgYH/kTU9nvThLtOjMb88MMy7I0QrwISD5ia0oeINm0of0UV3dyqZ+kwdv +/pTdt9Zas0zD37KOJZ9g//TBviioD4GQSd+2emEyyOqbRqdIW1O8lXYgpN3kwXPQ +XGSrcGfcVQp3cV1athZf7hmfH49+iGLbVcsKMudisLEC2bc4t6v6TjPhvDQoIcBV +k376IzehPsXttoyjW0nZZ1Vuz06XZiqBBR/ImPSAcURFGl8k28RJY3RRlQrq3WG8 +Qe69rwdsE2PlAy8GfhnmQma0N0B5vfG7K49cU4Db/bOYOnTGavfjI7VY4ipYJgpw +qx44m/g/zH1ZdQPWWaKnkV4o4oqymISOcFBTlajcPJGdy9qopzc+YGzbqux4XiEX +Ua+h3MKlLyjsO809kVBrMxA+w24Wrv3sP17B0+5KvqOdc1+BhewrVURzSwARAQAB +tDNTZWN1cml0eSBPcGVyYXRpb25zIEdBLUxvdHNlIDxzZWN1cml0eUBnYS1sb3Rz +ZS5kZT6JAk4EEwEIADgWIQQx+ix6Hl/MpaOJW4jrO2DO2XDM0QUCZvFLqAIbAwUL +CQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRDrO2DO2XDM0SqXEACHpbpcYUNdQX5f +/LgqawVaTKMH3noHpn7bG093oVmUaFWQ4IPKYTk82OKfYIt9RX2LaKXkaja04sa7 +RkAbJWcQzopzRd6QUyxm5MS1IKpctXrND9ZDnNEcvTvbNBSa2sgyfpmu/tiGdFYe +fKrHBIv00CR39z1O2fxrCrKJg45eH9iab0QSaq16r2vwcrgzm0mQzZv5V8R8UI8e +DBEXndymscebAOiWf47tH+GcHNffMzcywalD1BtJtnZwHK/9Hq9l052cbCeqQTyi +MaP+XRJ4iG7Rd5Tg15MkXkV5AHw9K8bGOErHLbmw4Dq3Df7cjSGb7btaMm6cuLWl +U/OsK6VLcLyTSGGrcybj2JTPP87QlEjOQvobxHNWf8NrEnSR7UncCuqpOv6SwyK4 +ltNKTRIXngzdexKF4ztCZGHyMKcASe+scWkTuaEx5ZMA12M4zUlCUVxIxzO7gnS0 +l0KUp2B+ULUidmix/MYum1bTrgxPt71h1tiXzv+UW9GUIzLoBYVojl6nCQ353gVa +VjvWfvQUBTOTXWNvDh712jlxniPDNsPrXsDmi8L6qK84UiB1oZ/G30i4cPFkMp3g +AMsw1U2eDATUcaYdT5mMpW7SMamoTOO28idqV/GSsycdNR+sV3UZAwh/GVvVr/4M +KduUaFcJrZYpXRyE5q64P/1/DyGoc7kCDQRm8UuoARAAqbIk/osc0OjiOVqcek6m +3cosEnwwX4ghmRB67xyU9rWy3kniyPcSAfKy1oj/Jr+oe7H+SEr9PuOQUT7NP6Ge +8427pb5gx7h/rfyiYqmlxhxIlYwSiZzp1wsnEzxFC3YMLUgGaCTdIICXI8g4K8sb +h8y1aMgjJ1OOxm/9L8RP0qCuuO5mwLjZvy59Gub2Pt8uVYTUfYJvxAjK1hjF0mHM +NVTZ0VCNJAxXykFPZTvbSY8gOlgtC4ru/HYyofYBJ8JYnqAfT5dpFQwrE3orTid/ +E1Dmn+n/kIG2JamVWWBVDEayr/fr4HT+R+G7vqJY/GNFpYQC7YrUlFtb3DvvzCSv +FQfwVWsyibQbHFkjCdAIISRGbjJnm/DtFzmRzjbL6VfQtjjBZ5m14cMKzFomfEVe +Lf/2kLNbuEj6jCVt2SNXmoknLkddWqy7B89zMcJF70dyStbaxiUMHg7RsVlpijrP +6meJeYMPcMqu2C6nDsfN2gDVcFXXakQU55hqgacEjns32MXfRFmRywTV/ybPI5Z/ +S9AAbFrPUW8PI4/pte+Od7xWARBXJN8TelZpiq1irwAEfqG5NUgitHnaN3Vl+x5j +WdtGSH/THA0mcvNKqQoquhcNUb7u+kmVQD3hi56wcQgNpOFjVlaGcTL1zIVXqBCW +zYRerrNQDQ2ZBNZPp9n/qu0AEQEAAYkCNgQYAQgAIBYhBDH6LHoeX8ylo4lbiOs7 +YM7ZcMzRBQJm8UuoAhsMAAoJEOs7YM7ZcMzRbM8P/jtd2JcwqS3UP4bbTpmIX1Ip +OJVX8r6dJEoot5YqxfaSvanR05OXTSQextithg/Ze8NcVXnHpdxcJMl0aVbeMDFS +/5sQCagwdUGACsOaGaH322JMCVYoiBSV4Z7l5xCINsvt460z1bkCPCCVkY5JqvM0 +sugeEj8B7GcaEuxr7/0iMJfrl2HUTZqoSgY6slveBhn012h/lafOhOEID9AGL2rL +1p+6tg2+7rckRqis17k0nTPKB9x8pkP+4QWug4Iygn5KkHh+iayiIIR1DyV3CxX0 +aYZpytvYHQllvUT9bWrozNu2mxIEraWBBoW1GkRTs0tnuWflpk6+xeBjDASNUSKS +7F4byhGsTLMKcBkPnUaaCd16EZ76D1hZ6k4RY5njCgM5CG0V0KlrsQDKQq4oGukH +I8qbScnJiKqHnhuolOj1dBZs3Oa8OD3ReUbWsztGwYMSe8YIXsmXmRQ+K89y4ANJ +Cx+dCuygOmiTdcxBZZaBdDbj1CUKrzv4Cx+sQtQoG7G5iAVmy8L6WCk1j16OY5sn +omLktFa8BzMUnC8PeXDRMRyhR65PcD6LAK/c/EY50HU9ksTzj11SE8MkvHcbYo9b +9Ml9pmy0/RoBw6sC+PedX/RImhjQg4m97wS4Dm20muzkloX+mpjKTHfaBDwsxORg +Jrh7G9TUA4U7m0/1OZeo +=4KvV +-----END PGP PUBLIC KEY BLOCK----- diff --git a/backend/buildSrc/src/main/groovy/eshg.image-push-sign.gradle b/backend/buildSrc/src/main/groovy/eshg.image-push-sign.gradle index 7916173636900372f701d17d123a9edb23afc5cc..9bd992f8755497b7eda0035ddede5be5f19f83c2 100644 --- a/backend/buildSrc/src/main/groovy/eshg.image-push-sign.gradle +++ b/backend/buildSrc/src/main/groovy/eshg.image-push-sign.gradle @@ -65,22 +65,26 @@ tasks.register('pushDockerImage', DockerPushImage) { } tasks.register("signDockerImage", Exec) { - def digest = "" - - commandLine 'cosign', 'sign', digest, - '--annotations', "com.gitlab.ci.pipeline.id=${System.getenv("CI_PIPELINE_ID")}", - '--annotations', "com.gitlab.ci.pipeline.url=${System.getenv("CI_PIPELINE_URL")}", - '--annotations', "com.gitlab.ci.job.id=${System.getenv("CI_JOB_ID")}", - '--annotations', "com.gitlab.ci.job.url=${System.getenv("CI_JOB_URL")}", - '--annotations', "com.gitlab.ci.commit.sha=${System.getenv("CI_COMMIT_SHA")}", - '--annotations', "com.gitlab.ci.commit.ref.name=${System.getenv("CI_COMMIT_REF_NAME")}", - '--annotations', "com.gitlab.ci.project.path=${System.getenv("CI_PROJECT_PATH")}", - '--annotations', "org.opencontainers.image.source=${System.getenv("CI_PROJECT_URL")}", - '--annotations', "org.opencontainers.image.revision=${System.getenv("CI_COMMIT_SHA")}" - doFirst { - assertTagNameIsGiven() - digest = getRepoDigest(getImageNameWithTag()) - } + doFirst { + assertTagNameIsGiven() + } + + def argProv = { + [ + 'sign', getRepoDigest(getImageNameWithTag()), + '--annotations', "com.gitlab.ci.pipeline.id=${System.getenv("CI_PIPELINE_ID")}".toString(), + '--annotations', "com.gitlab.ci.pipeline.url=${System.getenv("CI_PIPELINE_URL")}".toString(), + '--annotations', "com.gitlab.ci.job.id=${System.getenv("CI_JOB_ID")}".toString(), + '--annotations', "com.gitlab.ci.job.url=${System.getenv("CI_JOB_URL")}".toString(), + '--annotations', "com.gitlab.ci.commit.sha=${System.getenv("CI_COMMIT_SHA")}".toString(), + '--annotations', "com.gitlab.ci.commit.ref.name=${System.getenv("CI_COMMIT_REF_NAME")}".toString(), + '--annotations', "com.gitlab.ci.project.path=${System.getenv("CI_PROJECT_PATH")}".toString(), + '--annotations', "org.opencontainers.image.source=${System.getenv("CI_PROJECT_URL")}".toString(), + '--annotations', "org.opencontainers.image.revision=${System.getenv("CI_COMMIT_SHA")}".toString() + ] + } as CommandLineArgumentProvider + executable 'cosign' + argumentProviders.add(argProv) } tasks.register("verifyImageSignature", Exec) { @@ -96,4 +100,4 @@ tasks.register("verifyImageSignature", Exec) { assert project.hasProperty("certificateIdentity"): "certificateIdentity is necessary" assert project.hasProperty("certificateOidcIssuer"): "certificateOidcIssuer is necessary" } -} \ No newline at end of file +} diff --git a/backend/buildscript-gradle.lockfile b/backend/buildscript-gradle.lockfile index de384caf049db1bd391466f5f084e1e2d1c82311..65811731f91513f917a92654287270a1e8663e05 100644 --- a/backend/buildscript-gradle.lockfile +++ b/backend/buildscript-gradle.lockfile @@ -90,12 +90,12 @@ org.slf4j:slf4j-api:2.0.13=classpath org.sonarqube:org.sonarqube.gradle.plugin:5.1.0.4882=classpath org.sonarsource.scanner.api:sonar-scanner-api:2.16.2.588=classpath org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:5.1.0.4882=classpath -org.springframework.boot:org.springframework.boot.gradle.plugin:3.3.3=classpath -org.springframework.boot:spring-boot-buildpack-platform:3.3.3=classpath -org.springframework.boot:spring-boot-gradle-plugin:3.3.3=classpath -org.springframework.boot:spring-boot-loader-tools:3.3.3=classpath -org.springframework:spring-core:6.1.12=classpath -org.springframework:spring-jcl:6.1.12=classpath +org.springframework.boot:org.springframework.boot.gradle.plugin:3.3.4=classpath +org.springframework.boot:spring-boot-buildpack-platform:3.3.4=classpath +org.springframework.boot:spring-boot-gradle-plugin:3.3.4=classpath +org.springframework.boot:spring-boot-loader-tools:3.3.4=classpath +org.springframework:spring-core:6.1.13=classpath +org.springframework:spring-jcl:6.1.13=classpath org.tomlj:tomlj:1.0.0=classpath org.tukaani:xz:1.9=classpath org.webjars:d3js:4.10.2=classpath diff --git a/backend/business-module-commons/build.gradle b/backend/business-module-commons/build.gradle index bd8d82fa790c6a55cdd1e74cfa98dad6188d2024..4816308bf33fcaecf8994b76fe2540f25587e611 100644 --- a/backend/business-module-commons/build.gradle +++ b/backend/business-module-commons/build.gradle @@ -11,7 +11,7 @@ dependencies { api project(':test-helper-commons') api project(':lib-commons') api project(':lib-security-config') - implementation project(':rest-service-commons') + runtimeOnly project(':rest-service-commons') api 'org.springframework.boot:spring-boot-starter-web' api 'org.springframework.boot:spring-boot-starter-actuator' @@ -29,7 +29,7 @@ dependencies { compileOnly 'org.jetbrains:annotations:latest.release' testImplementation project(':test-commons') - testImplementation testFixtures(project(':rest-service-commons')) + testImplementation project(':rest-service-commons') testFixturesApi project(':test-commons') testFixturesApi 'org.springframework.boot:spring-boot-testcontainers' diff --git a/backend/business-module-commons/gradle.lockfile b/backend/business-module-commons/gradle.lockfile index 1b6f2ea29600119349808ed6a79c192593a711e6..7d2febf9cf1ef7003636b7982d2f9f0bf40a0033 100644 --- a/backend/business-module-commons/gradle.lockfile +++ b/backend/business-module-commons/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -35,17 +36,17 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testFixturesRuntimeClasspath,t com.tngtech.archunit:archunit-junit5:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testFixturesRuntimeClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -53,14 +54,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=compileClasspath,productionRuntimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -80,10 +80,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath @@ -99,7 +99,7 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testFixturesCompileClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -125,7 +125,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testFixturesCompileClasspat org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testFixturesRuntimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testFixturesRuntimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -133,25 +133,25 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -160,16 +160,16 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.19.8=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.webjars:swagger-ui:5.17.14=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath diff --git a/backend/business-module-commons/src/main/java/de/base/rest/CustomMediaTypes.java b/backend/business-module-commons/src/main/java/de/base/rest/CustomMediaTypes.java index 0593695ec06a71df4fa303d0176f730c5b2739d2..541b9f1ba8a5b296ff39cc0ffa0d1b7f7ee8689e 100644 --- a/backend/business-module-commons/src/main/java/de/base/rest/CustomMediaTypes.java +++ b/backend/business-module-commons/src/main/java/de/base/rest/CustomMediaTypes.java @@ -20,6 +20,9 @@ public class CustomMediaTypes { public static final String ZIP_VALUE = "application/zip"; public static final MediaType ZIP = MediaType.valueOf(ZIP_VALUE); + public static final String TEXT_PLAIN_UTF_8_VALUE = "text/plain;charset=utf-8"; + public static final MediaType TEXT_PLAIN_UTF_8 = MediaType.valueOf(TEXT_PLAIN_UTF_8_VALUE); + public static final String APPLICATION_XLSX_VALUE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; public static final MediaType APPLICATION_XLSX = MediaType.valueOf(APPLICATION_XLSX_VALUE); diff --git a/backend/business-module-commons/src/main/java/de/eshg/rest/service/error/GlobalExceptionHandler.java b/backend/business-module-commons/src/main/java/de/eshg/rest/service/error/GlobalExceptionHandler.java index be0b6f1f0dff86037a75399ee7d138691f02cf12..dbf81b605dd8ac4f2a8afbf04815a4b3c95ea01b 100644 --- a/backend/business-module-commons/src/main/java/de/eshg/rest/service/error/GlobalExceptionHandler.java +++ b/backend/business-module-commons/src/main/java/de/eshg/rest/service/error/GlobalExceptionHandler.java @@ -5,6 +5,8 @@ package de.eshg.rest.service.error; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import java.util.LinkedHashMap; @@ -59,7 +61,18 @@ public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { @NotNull HttpStatusCode status, @NotNull WebRequest request) { log.error("Bad Request", ex); - return ResponseEntity.badRequest().body(ex.getMessage()); + String errorMessage; + Throwable cause = ex.getCause(); + if (cause instanceof JsonParseException) { + errorMessage = "Invalid JSON format."; + } else if (cause instanceof JsonMappingException) { + errorMessage = "Error in mapping if JSON data."; + } else if (ex.getMessage().contains("Required request body is missing")) { + errorMessage = "Required request body is missing"; + } else { + errorMessage = "The request contains invalid data"; + } + return ResponseEntity.badRequest().body(errorMessage); } @Override diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/utils/RequestParameterUtil.java b/backend/business-module-commons/src/main/java/de/eshg/rest/service/validation/RequestParameterUtil.java similarity index 88% rename from backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/utils/RequestParameterUtil.java rename to backend/business-module-commons/src/main/java/de/eshg/rest/service/validation/RequestParameterUtil.java index 36d0eb478f8c232fa964632c6a6fa629ba02ab3b..3b2822717c2b0f01fdb532905ca022305585bf4a 100644 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/utils/RequestParameterUtil.java +++ b/backend/business-module-commons/src/main/java/de/eshg/rest/service/validation/RequestParameterUtil.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package de.eshg.rest.service.commons.utils; +package de.eshg.rest.service.validation; import static java.util.function.Predicate.not; @@ -13,7 +13,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -27,7 +26,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.support.BindParamNameResolver; -public final class RequestParameterUtil { +final class RequestParameterUtil { private static final BindParamNameResolver BIND_PARAM_NAME_RESOLVER = new BindParamNameResolver(); private static final Set<Class<? extends Annotation>> REQUEST_PARAMETER_ANNOTATIONS = @@ -41,7 +40,7 @@ public final class RequestParameterUtil { .collect(Collectors.toSet()); } - public static Stream<MethodParameter> getMethodParameters(AnnotatedMethod handlerMethod) { + private static Stream<MethodParameter> getMethodParameters(AnnotatedMethod handlerMethod) { return Stream.concat( getNonNestedParameters(handlerMethod), getNestedMethodParameters(handlerMethod)); } @@ -51,20 +50,11 @@ public final class RequestParameterUtil { .filter(parameter -> !BeanUtils.isSimpleProperty(parameter.getParameterType())) .filter(RequestParameterUtil::isNotAnnotatedWithSpringRequestAnnotations) .map(MethodParameter::getParameterType) - .map(RequestParameterUtil::findResolvableConstructor) - .filter(Objects::nonNull) + .map(BeanUtils::getResolvableConstructor) .map(RequestParameterUtil::getMethodParameters) .flatMap(Collection::stream); } - private static <T> Constructor<T> findResolvableConstructor(Class<T> aClass) { - try { - return BeanUtils.getResolvableConstructor(aClass); - } catch (IllegalStateException e) { - return null; - } - } - private static List<MethodParameter> getMethodParameters(Constructor<?> constructor) { List<MethodParameter> methodParameters = new ArrayList<>(); String[] parameterNames = BeanUtils.getParameterNames(constructor); @@ -94,7 +84,7 @@ public final class RequestParameterUtil { || methodParameter.hasParameterAnnotation(RequestPart.class); } - public static String resolveRequestParameterName(MethodParameter methodParameter) { + private static String resolveRequestParameterName(MethodParameter methodParameter) { if (methodParameter.hasParameterAnnotation(RequestParam.class)) { return resolveRequestParamAnnotatedName(methodParameter); } diff --git a/backend/business-module-commons/src/main/java/de/eshg/rest/service/validation/UnknownQueryParameterValidator.java b/backend/business-module-commons/src/main/java/de/eshg/rest/service/validation/UnknownQueryParameterValidator.java index 2a62b6dc9c2f462a5d2a9391ef97827b85a2bf2e..b22cd3fdc936dd8cb202961f18e171033c68db19 100644 --- a/backend/business-module-commons/src/main/java/de/eshg/rest/service/validation/UnknownQueryParameterValidator.java +++ b/backend/business-module-commons/src/main/java/de/eshg/rest/service/validation/UnknownQueryParameterValidator.java @@ -5,7 +5,6 @@ package de.eshg.rest.service.validation; -import de.eshg.rest.service.commons.utils.RequestParameterUtil; import de.eshg.rest.service.error.BadRequestException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; diff --git a/backend/business-module-persistence-commons/build.gradle b/backend/business-module-persistence-commons/build.gradle index 49f0fc06a1a38052ce49b9e1dc5d38a933516934..0fe8126e819c6bd0be4150c331fa64d3475c244e 100644 --- a/backend/business-module-persistence-commons/build.gradle +++ b/backend/business-module-persistence-commons/build.gradle @@ -12,11 +12,13 @@ dependencies { annotationProcessor 'org.hibernate.orm:hibernate-jpamodelgen' implementation 'org.liquibase:liquibase-core' + implementation 'de.cronn:reflection-util:latest.release' runtimeOnly 'de.cronn:liquibase-postgres-enum-extension:latest.release' testFixturesApi testFixtures(project(':business-module-commons')) testFixturesImplementation project(':test-commons') + testFixturesImplementation project(':rest-service-commons') testFixturesImplementation 'org.springframework.boot:spring-boot-test' testFixturesApi 'de.cronn:liquibase-changelog-generator-postgresql:latest.release' } diff --git a/backend/business-module-persistence-commons/gradle.lockfile b/backend/business-module-persistence-commons/gradle.lockfile index 38b22f8043fb722f0e02266c1dce6b42464020f3..375f5735420691d117b1bac166feba3a820d03e2 100644 --- a/backend/business-module-persistence-commons/gradle.lockfile +++ b/backend/business-module-persistence-commons/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -37,20 +38,20 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testFixturesRuntimeClasspath,testRunt com.tngtech.archunit:archunit:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testFixturesRuntimeClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +de.cronn:reflection-util:2.17.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -58,14 +59,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -88,10 +88,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -108,9 +108,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testFixturesCompileClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -136,7 +136,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testFixturesCompileClasspat org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testFixturesRuntimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testFixturesRuntimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -144,29 +144,29 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -175,19 +175,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath diff --git a/backend/business-module-persistence-commons/src/main/java/de/eshg/persistence/ControlCharacterValidationEventListener.java b/backend/business-module-persistence-commons/src/main/java/de/eshg/persistence/ControlCharacterValidationEventListener.java new file mode 100644 index 0000000000000000000000000000000000000000..0600582ceb8f748dbde2b1045bbf4c8ed3a7eb6b --- /dev/null +++ b/backend/business-module-persistence-commons/src/main/java/de/eshg/persistence/ControlCharacterValidationEventListener.java @@ -0,0 +1,65 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.persistence; + +import de.cronn.reflection.util.PropertyUtils; +import java.beans.PropertyDescriptor; +import org.hibernate.event.spi.*; + +public class ControlCharacterValidationEventListener + implements PreInsertEventListener, PreUpdateEventListener { + + @Override + public boolean onPreInsert(PreInsertEvent event) { + return validateEntity(event); + } + + @Override + public boolean onPreUpdate(PreUpdateEvent event) { + return validateEntity(event); + } + + private boolean validateEntity(AbstractPreDatabaseOperationEvent event) { + Object entity = event.getEntity(); + Object primaryKey = event.getId(); + + for (PropertyDescriptor propertyDescriptor : PropertyUtils.getPropertyDescriptors(entity)) { + if (propertyDescriptor.getPropertyType().equals(String.class)) { + String value = PropertyUtils.read(entity, propertyDescriptor); + if (containsDisallowedControlCharacters(value)) { + String qualifiedPropertyName = + PropertyUtils.getQualifiedPropertyName(entity, propertyDescriptor); + throw new IllegalArgumentException( + "Disallowed control character in %s with primary key %s." + .formatted(qualifiedPropertyName, primaryKey)); + } + } + } + + return false; + } + + private static boolean containsDisallowedControlCharacters(String value) { + if (value == null) { + return false; + } + + for (int i = 0; i < value.length(); i++) { + char c = value.charAt(i); + + // Allow newline (\n), tab (\t), and carriage return (\r) + if (c == '\n' || c == '\t' || c == '\r') { + continue; + } + + // save to use since control characters do not exist in the supplementary character ranges + if (Character.isISOControl(c)) { + return true; + } + } + return false; + } +} diff --git a/backend/business-module-persistence-commons/src/main/java/de/eshg/persistence/EshgHibernateEventListenerConfiguration.java b/backend/business-module-persistence-commons/src/main/java/de/eshg/persistence/EshgHibernateEventListenerConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..32ef6002b3e832527dd361bd24af4d2a845d361f --- /dev/null +++ b/backend/business-module-persistence-commons/src/main/java/de/eshg/persistence/EshgHibernateEventListenerConfiguration.java @@ -0,0 +1,39 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.persistence; + +import jakarta.annotation.PostConstruct; +import jakarta.persistence.EntityManagerFactory; +import org.hibernate.event.service.spi.EventListenerRegistry; +import org.hibernate.event.spi.EventType; +import org.hibernate.internal.SessionFactoryImpl; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Bean; + +@AutoConfiguration +public class EshgHibernateEventListenerConfiguration { + private final EntityManagerFactory entityManagerFactory; + + public EshgHibernateEventListenerConfiguration(EntityManagerFactory entityManagerFactory) { + this.entityManagerFactory = entityManagerFactory; + } + + @Bean + public ControlCharacterValidationEventListener characterVerificationEventListener() { + return new ControlCharacterValidationEventListener(); + } + + @PostConstruct + public void registerListeners() { + SessionFactoryImpl sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl.class); + EventListenerRegistry registry = + sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class); + ControlCharacterValidationEventListener listener = characterVerificationEventListener(); + assert registry != null; + registry.getEventListenerGroup(EventType.PRE_INSERT).appendListener(listener); + registry.getEventListenerGroup(EventType.PRE_UPDATE).appendListener(listener); + } +} diff --git a/backend/business-module-persistence-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/backend/business-module-persistence-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 7558262444914ccb3e44e7f18adbd04e5d985e24..aafc3a05df1450da727f6c970a33a479c95e5f96 100644 --- a/backend/business-module-persistence-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/backend/business-module-persistence-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -2,3 +2,4 @@ de.eshg.persistence.EshgJpaAutoConfiguration de.eshg.persistence.EshgDefaultRevisionEntityAuditingConfiguration de.eshg.persistence.TransactionHelper de.eshg.jpaauditing.JpaAuditingAutoConfiguration +de.eshg.persistence.EshgHibernateEventListenerConfiguration diff --git a/backend/central-repository/gradle.lockfile b/backend/central-repository/gradle.lockfile index 42610e60dc83adc8da94df1e838ebcc1ff54882e..88f7ba4c506765ec9f7052d1ee385e8eec004556 100644 --- a/backend/central-repository/gradle.lockfile +++ b/backend/central-repository/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -38,7 +39,7 @@ com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.15.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -46,11 +47,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -58,9 +59,9 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -92,10 +93,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -112,8 +113,8 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -139,7 +140,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -147,30 +148,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.retry:spring-retry:2.0.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.retry:spring-retry:2.0.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -179,19 +180,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath diff --git a/backend/chat-management/gradle.lockfile b/backend/chat-management/gradle.lockfile index ff268b5303fffc824da2a76f936f9078532abe52..f8fbc4998f5f588a54ee80d14e21f9ce4a404468 100644 --- a/backend/chat-management/gradle.lockfile +++ b/backend/chat-management/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -38,8 +39,8 @@ com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-codec:commons-codec:1.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -47,11 +48,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -59,14 +60,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -90,10 +90,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -110,9 +110,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -138,7 +138,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -146,29 +146,29 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -177,19 +177,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/compliance-test/gradle.lockfile b/backend/compliance-test/gradle.lockfile index ed765e63a4baaada3df8b4bfcfac7ecdabc681bc..fe81e0751e379f894ac4bc807a5580af9379d04e 100644 --- a/backend/compliance-test/gradle.lockfile +++ b/backend/compliance-test/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.adobe.xmp:xmpcore:6.1.11=testRuntimeClasspath com.drewnoakes:metadata-extractor:2.19.0=testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=testCompileClasspath,testRuntimeClasspath @@ -35,9 +35,9 @@ com.github.virtuald:curvesapi:1.08=testRuntimeClasspath com.google.code.findbugs:jsr305:3.0.2=testCompileClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=testCompileClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=testCompileClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=testCompileClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=testCompileClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=testCompileClasspath,testRuntimeClasspath -com.google.j2objc:j2objc-annotations:3.0.0=testCompileClasspath +com.google.j2objc:j2objc-annotations:3.0.0=testCompileClasspath,testRuntimeClasspath com.google.protobuf:protobuf-javalite:3.23.4=testRuntimeClasspath com.google.zxing:core:3.5.3=testRuntimeClasspath com.googlecode.ez-vcard:ez-vcard:0.12.1=testRuntimeClasspath @@ -100,9 +100,9 @@ com.zaxxer:SparseBitSet:1.3=testRuntimeClasspath commons-beanutils:commons-beanutils:1.9.4=testRuntimeClasspath commons-codec:commons-codec:1.16.1=testRuntimeClasspath commons-collections:commons-collections:3.2.2=testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath commons-logging:commons-logging:1.3.3=testRuntimeClasspath -de.cronn:commons-lang:1.1=testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=testRuntimeClasspath @@ -112,40 +112,40 @@ de.rototor.pdfbox:graphics2d:3.0.1=testRuntimeClasspath de.topobyte:adt-multicollections:0.0.4=testRuntimeClasspath de.topobyte:osm4j-core:1.3.0=testRuntimeClasspath de.topobyte:osm4j-pbf:1.3.0=testRuntimeClasspath -dnsjava:dnsjava:3.6.1=testRuntimeClasspath -io.github.hakky54:sslcontext-kickstart-for-netty:8.3.6=testRuntimeClasspath -io.github.hakky54:sslcontext-kickstart:8.3.6=testRuntimeClasspath +dnsjava:dnsjava:3.6.2=testRuntimeClasspath +io.github.hakky54:sslcontext-kickstart-for-netty:8.3.7=testRuntimeClasspath +io.github.hakky54:sslcontext-kickstart:8.3.7=testRuntimeClasspath io.github.java-diff-utils:java-diff-utils:4.12=testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-core:1.1.22=testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-pdfbox:1.1.22=testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-slf4j:1.1.22=testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-svg-support:1.1.22=testRuntimeClasspath io.lettuce:lettuce-core:6.3.2.RELEASE=testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=testRuntimeClasspath -io.netty:netty-buffer:4.1.112.Final=testRuntimeClasspath -io.netty:netty-codec-dns:4.1.112.Final=testRuntimeClasspath -io.netty:netty-codec-http2:4.1.112.Final=testRuntimeClasspath -io.netty:netty-codec-http:4.1.112.Final=testRuntimeClasspath -io.netty:netty-codec-socks:4.1.112.Final=testRuntimeClasspath -io.netty:netty-codec:4.1.112.Final=testRuntimeClasspath -io.netty:netty-common:4.1.112.Final=testRuntimeClasspath -io.netty:netty-handler-proxy:4.1.112.Final=testRuntimeClasspath -io.netty:netty-handler:4.1.112.Final=testRuntimeClasspath -io.netty:netty-resolver-dns-classes-macos:4.1.112.Final=testRuntimeClasspath -io.netty:netty-resolver-dns-native-macos:4.1.112.Final=testRuntimeClasspath -io.netty:netty-resolver-dns:4.1.112.Final=testRuntimeClasspath -io.netty:netty-resolver:4.1.112.Final=testRuntimeClasspath -io.netty:netty-transport-classes-epoll:4.1.112.Final=testRuntimeClasspath -io.netty:netty-transport-native-epoll:4.1.112.Final=testRuntimeClasspath -io.netty:netty-transport-native-unix-common:4.1.112.Final=testRuntimeClasspath -io.netty:netty-transport:4.1.112.Final=testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=testRuntimeClasspath +io.netty:netty-buffer:4.1.113.Final=testRuntimeClasspath +io.netty:netty-codec-dns:4.1.113.Final=testRuntimeClasspath +io.netty:netty-codec-http2:4.1.113.Final=testRuntimeClasspath +io.netty:netty-codec-http:4.1.113.Final=testRuntimeClasspath +io.netty:netty-codec-socks:4.1.113.Final=testRuntimeClasspath +io.netty:netty-codec:4.1.113.Final=testRuntimeClasspath +io.netty:netty-common:4.1.113.Final=testRuntimeClasspath +io.netty:netty-handler-proxy:4.1.113.Final=testRuntimeClasspath +io.netty:netty-handler:4.1.113.Final=testRuntimeClasspath +io.netty:netty-resolver-dns-classes-macos:4.1.113.Final=testRuntimeClasspath +io.netty:netty-resolver-dns-native-macos:4.1.113.Final=testRuntimeClasspath +io.netty:netty-resolver-dns:4.1.113.Final=testRuntimeClasspath +io.netty:netty-resolver:4.1.113.Final=testRuntimeClasspath +io.netty:netty-transport-classes-epoll:4.1.113.Final=testRuntimeClasspath +io.netty:netty-transport-native-epoll:4.1.113.Final=testRuntimeClasspath +io.netty:netty-transport-native-unix-common:4.1.113.Final=testRuntimeClasspath +io.netty:netty-transport:4.1.113.Final=testRuntimeClasspath io.projectreactor.netty:reactor-netty-core:1.1.22=testRuntimeClasspath io.projectreactor.netty:reactor-netty-http:1.1.22=testRuntimeClasspath -io.projectreactor:reactor-core:3.6.9=testRuntimeClasspath +io.projectreactor:reactor-core:3.6.10=testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=testRuntimeClasspath @@ -153,8 +153,8 @@ io.prometheus:prometheus-metrics-model:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=testRuntimeClasspath io.smallrye:jandex:3.1.2=testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations:2.2.23=testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations:2.2.24=testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=testCompileClasspath,testRuntimeClasspath io.swagger:swagger-annotations:1.6.14=testCompileClasspath,testRuntimeClasspath @@ -221,10 +221,10 @@ org.apache.tika:tika-bom:2.9.2=testRuntimeClasspath org.apache.tika:tika-core:2.9.2=testRuntimeClasspath org.apache.tika:tika-parser-pdf-module:2.9.2=testRuntimeClasspath org.apache.tika:tika-parser-xmp-commons:2.9.2=testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=testRuntimeClasspath org.apache.ws.xmlschema:xmlschema-core:2.3.1=testCompileClasspath,testRuntimeClasspath org.apache.xmlbeans:xmlbeans:5.2.1=testRuntimeClasspath org.apache.xmlgraphics:batik-anim:1.17=testRuntimeClasspath @@ -273,8 +273,8 @@ org.hamcrest:hamcrest-core:2.2=testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=testCompileClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -301,9 +301,9 @@ org.junit.platform:junit-platform-commons:1.10.3=testCompileClasspath,testRuntim org.junit.platform:junit-platform-engine:1.10.3=testRuntimeClasspath org.junit.platform:junit-platform-launcher:1.10.3=testRuntimeClasspath org.junit:junit-bom:5.10.3=testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-admin-client:25.0.4=testRuntimeClasspath -org.keycloak:keycloak-common:25.0.4=testRuntimeClasspath -org.keycloak:keycloak-core:25.0.4=testRuntimeClasspath +org.keycloak:keycloak-admin-client:25.0.6=testRuntimeClasspath +org.keycloak:keycloak-common:25.0.6=testRuntimeClasspath +org.keycloak:keycloak-core:25.0.6=testRuntimeClasspath org.latencyutils:LatencyUtils:2.0.3=testRuntimeClasspath org.liquibase:liquibase-core:4.27.0=testRuntimeClasspath org.mnode.ical4j:ical4j:4.0.4=testRuntimeClasspath @@ -316,7 +316,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.reactivestreams:reactive-streams:1.0.4=testRuntimeClasspath org.reflections:reflections:0.10.2=testCompileClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testRuntimeClasspath @@ -324,36 +324,36 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-redis:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-mail:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-thymeleaf:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-websocket:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-keyvalue:3.3.3=testRuntimeClasspath -org.springframework.data:spring-data-redis:3.3.3=testRuntimeClasspath -org.springframework.retry:spring-retry:2.0.8=testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-redis:3.3.4=testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-mail:3.3.4=testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-thymeleaf:3.3.4=testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-websocket:3.3.4=testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-keyvalue:3.3.4=testRuntimeClasspath +org.springframework.data:spring-data-redis:3.3.4=testRuntimeClasspath +org.springframework.retry:spring-retry:2.0.9=testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=testCompileClasspath,testRuntimeClasspath @@ -364,23 +364,23 @@ org.springframework.security:spring-security-oauth2-resource-server:6.3.3=testCo org.springframework.security:spring-security-web:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.session:spring-session-core:3.3.2=testRuntimeClasspath org.springframework.session:spring-session-data-redis:3.3.2=testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context-support:6.1.12=testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-messaging:6.1.12=testRuntimeClasspath -org.springframework:spring-orm:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-oxm:6.1.12=testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-websocket:6.1.12=testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context-support:6.1.13=testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-messaging:6.1.13=testRuntimeClasspath +org.springframework:spring-orm:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-oxm:6.1.13=testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-websocket:6.1.13=testRuntimeClasspath org.testcontainers:testcontainers:1.19.8=testRuntimeClasspath org.threeten:threeten-extra:1.8.0=testRuntimeClasspath org.thymeleaf:thymeleaf-spring6:3.1.2.RELEASE=testRuntimeClasspath diff --git a/backend/docker-compose.yaml b/backend/docker-compose.yaml index 92b3e56654612d8ebf391fe9b7b1463e77307a75..8cf8939f7db28da05e4e4e4ce75d40f44f9994d5 100644 --- a/backend/docker-compose.yaml +++ b/backend/docker-compose.yaml @@ -402,10 +402,12 @@ services: image: matrixdotorg/synapse:v1.114.0@sha256:0983d976eaaed08af558b8ce720caa89340124146e0c6e49042c9072acff7919 environment: - SYNAPSE_SERVER_NAME=synapse.local.dev - - UID=1000 - - GID=1000 + - UID=0 + - GID=0 volumes: - - ./resources/matrix/synapse:/data + - ./resources/matrix/synapse/media_store:/data/media_store + - ./resources/matrix/synapse/homeserver.yaml:/data/homeserver.yaml + - ./resources/matrix/synapse/synapse.local.dev.log.config:/data/synapse.local.dev.log.config ports: - "${SYNAPSE_HTTP_PORT:-8008}:8008" healthcheck: @@ -443,6 +445,8 @@ services: sti-protection: image: ga-lotse/sti-protection + env_file: + - 'lib-procedures/src/test/resources/archiving-test.env' environment: - spring.profiles.active=${ACTIVE_SPRING_PROFILES:-test-helper} - spring.datasource.url=jdbc:postgresql://sti-protection-db/sti_protection diff --git a/backend/gradlew.bat b/backend/gradlew.bat index 9b42019c7915b971238526075306ffba3b666dd5..9d21a21834d5195c278ba17baec3115b2aaab06e 100644 Binary files a/backend/gradlew.bat and b/backend/gradlew.bat differ diff --git a/backend/inspection/gradle.lockfile b/backend/inspection/gradle.lockfile index fd4ba8c4b0af3e328a4a318203e8a7c4609cfcea..d73e0b6cf2fd53f96a8121b9de9c9dbe71b91ed7 100644 --- a/backend/inspection/gradle.lockfile +++ b/backend/inspection/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.adobe.xmp:xmpcore:6.1.11=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.drewnoakes:metadata-extractor:2.19.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -25,8 +25,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.protobuf:protobuf-javalite:3.23.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -79,9 +80,9 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath commons-logging:commons-logging:1.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -97,11 +98,11 @@ io.github.openhtmltopdf:openhtmltopdf-core:1.1.22=productionRuntimeClasspath,run io.github.openhtmltopdf:openhtmltopdf-pdfbox:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-slf4j:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-svg-support:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -109,7 +110,7 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -155,10 +156,10 @@ org.apache.tika:tika-bom:2.9.2=productionRuntimeClasspath,runtimeClasspath,testR org.apache.tika:tika-core:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-pdf-module:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-xmp-commons:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-anim:1.17=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-awt-util:1.17=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-bridge:1.17=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -197,9 +198,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -226,7 +227,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -234,30 +235,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -267,19 +268,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/inspection/openApi.yaml b/backend/inspection/openApi.yaml index 254d03f57284b61385b99491e56c83441a988b8c..51f5a89d47625a1ac878f98b609247673497c7bc 100644 --- a/backend/inspection/openApi.yaml +++ b/backend/inspection/openApi.yaml @@ -439,6 +439,32 @@ paths: definition in the central repository tags: - ChecklistDefinitionCentralRepo + /checklists/definitions/versions/{id}: + put: + operationId: editDraftChecklistDefinitionVersion + parameters: + - in: path + name: id + required: true + schema: + type: string + format: uuid + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ChecklistDefinitionVersionRequest" + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/ChecklistDefinitionVersion" + description: OK + summary: Edits an existing checklist definition version in draft mode + tags: + - ChecklistDefinition /checklists/definitions/versions/{versionId}: get: operationId: getChecklistDefinitionVersion @@ -473,7 +499,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/AddChecklistDefinitionVersionRequest" + $ref: "#/components/schemas/ChecklistDefinitionVersionRequest" required: true responses: "200": @@ -3386,24 +3412,6 @@ components: minimum: 1 required: - barrierId - AddChecklistDefinitionVersionRequest: - type: object - properties: - deleted: - type: boolean - description: - type: string - isExpandable: - type: boolean - name: - type: string - sections: - type: array - items: - $ref: "#/components/schemas/CLSectionContext" - required: - - name - - sections AddFacilityFileStateRequest: type: object description: Request used for adding facilities from non-external sources @@ -3575,8 +3583,12 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 required: - assignee + - taskVersion BulkUpdateProceduresArchivingRelevanceRequest: type: object properties: @@ -3731,8 +3743,13 @@ components: id: type: string format: uuid + lastModified: + type: string + format: date-time name: type: string + published: + type: boolean repositoryVersion: type: integer format: int32 @@ -3755,8 +3772,8 @@ components: - expandable - id - name + - published - sections - - validFrom - version CLElement: type: object @@ -4071,25 +4088,28 @@ components: type: boolean deleted: type: boolean + expandable: + type: boolean id: type: string format: uuid + lastModified: + type: string + format: date-time mostRecentRepositoryVersion: type: integer format: int32 + mostRecentVersion: + $ref: "#/components/schemas/ChecklistDefinitionVersion" mostRecentVersionBasedOnRepo: type: integer format: int32 - mostRecentVersionId: - type: string - format: uuid - mostRecentVersionNr: - type: integer - format: int32 name: type: string objectType: $ref: "#/components/schemas/ObjectTypeRef" + published: + type: boolean versions: type: array items: @@ -4097,10 +4117,12 @@ components: required: - coreChecklist - deleted + - expandable - id - - mostRecentVersionId - - mostRecentVersionNr + - lastModified + - mostRecentVersion - name + - published - versions ChecklistDefinitionCentralRepoMetadata: type: object @@ -4206,6 +4228,8 @@ components: properties: context: $ref: "#/components/schemas/CLContext" + hasDraft: + type: boolean isCoreChecklist: type: boolean modifiedBy: @@ -4214,6 +4238,26 @@ components: $ref: "#/components/schemas/ObjectTypeRef" required: - context + ChecklistDefinitionVersionRequest: + type: object + properties: + deleted: + type: boolean + description: + type: string + isExpandable: + type: boolean + name: + type: string + published: + type: boolean + sections: + type: array + items: + $ref: "#/components/schemas/CLSectionContext" + required: + - name + - sections ChecklistDefinitionsResponse: type: object properties: @@ -4650,6 +4694,8 @@ components: objectTypeId: type: string format: uuid + published: + type: boolean sections: type: array items: @@ -5328,7 +5374,7 @@ components: - totalPages GetArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - PROCEDURE_TYPE @@ -5786,7 +5832,7 @@ components: - totalPages GetRelevantArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - EXPORTED_AT @@ -7358,6 +7404,11 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 + required: + - taskVersion SingleObjectTypeResponse: type: object properties: @@ -7447,6 +7498,9 @@ components: $ref: "#/components/schemas/TaskStatus" taskType: $ref: "#/components/schemas/TaskType" + version: + type: integer + format: int64 required: - businessModule - createdAt @@ -7457,6 +7511,7 @@ components: - taskId - taskStatus - taskType + - version TaskMetric: type: object properties: diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/ChecklistContextDto.java b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/ChecklistContextDto.java index becd496382ded8db145936651579f249c9650cf9..e3725859f42fe55da026cb701654395db3701ed9 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/ChecklistContextDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/ChecklistContextDto.java @@ -19,10 +19,12 @@ public class ChecklistContextDto { // This is a ChecklistDefinitionVersion entit private @NotNull UUID defId; private @NotNull String name; private String description; - private @NotNull Instant validFrom; + private Instant validFrom; private Instant validTo; private @NotNull boolean expandable; private @NotNull boolean deleted; + private @NotNull boolean published; + private Instant lastModified; private @NotNull int version; private Integer repositoryVersion; private @NotNull @Valid List<ChecklistSectionContextDto> sections; @@ -91,6 +93,22 @@ public class ChecklistContextDto { // This is a ChecklistDefinitionVersion entit this.deleted = deleted; } + public boolean isPublished() { + return published; + } + + public void setPublished(boolean published) { + this.published = published; + } + + public Instant getLastModified() { + return lastModified; + } + + public void setLastModified(Instant lastModified) { + this.lastModified = lastModified; + } + public int getVersion() { return version; } @@ -121,6 +139,8 @@ public class ChecklistContextDto { // This is a ChecklistDefinitionVersion entit if (o == null || getClass() != o.getClass()) return false; ChecklistContextDto that = (ChecklistContextDto) o; return expandable == that.expandable + && deleted == that.deleted + && published == that.published && version == that.version && Objects.equals(id, that.id) && Objects.equals(defId, that.defId) @@ -128,6 +148,7 @@ public class ChecklistContextDto { // This is a ChecklistDefinitionVersion entit && Objects.equals(description, that.description) && Objects.equals(validFrom, that.validFrom) && Objects.equals(validTo, that.validTo) + && Objects.equals(lastModified, that.lastModified) && Objects.equals(repositoryVersion, that.repositoryVersion) && Objects.equals(sections, that.sections); } @@ -142,8 +163,45 @@ public class ChecklistContextDto { // This is a ChecklistDefinitionVersion entit validFrom, validTo, expandable, + deleted, + published, + lastModified, version, repositoryVersion, sections); } + + @Override + public String toString() { + return "ChecklistContextDto{" + + "id=" + + id + + ", defId=" + + defId + + ", name='" + + name + + '\'' + + ", description='" + + description + + '\'' + + ", validFrom=" + + validFrom + + ", validTo=" + + validTo + + ", expandable=" + + expandable + + ", deleted=" + + deleted + + ", published=" + + published + + ", lastModified=" + + lastModified + + ", version=" + + version + + ", repositoryVersion=" + + repositoryVersion + + ", sections=" + + sections + + '}'; + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/ChecklistSectionContextDto.java b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/ChecklistSectionContextDto.java index 0b1deacc5ef3885ed30c5c47057597b624803199..5a75a0ecb4b42c9accd42b45df95f0a0c718d68f 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/ChecklistSectionContextDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/ChecklistSectionContextDto.java @@ -58,4 +58,17 @@ public class ChecklistSectionContextDto { public int hashCode() { return Objects.hash(id, title, elements); } + + @Override + public String toString() { + return "ChecklistSectionContextDto{" + + "id=" + + id + + ", title='" + + title + + '\'' + + ", elements=" + + elements + + '}'; + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/ChecklistElementContextDto.java b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/ChecklistElementContextDto.java index 489e8d51584edec4785a47162119093be4c6edbd..d9d9b7dee87769e4320f93c2ca4cf86b0f3d54d9 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/ChecklistElementContextDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/ChecklistElementContextDto.java @@ -78,4 +78,9 @@ public abstract class ChecklistElementContextDto { public int hashCode() { return Objects.hash(id); } + + @Override + public String toString() { + return "ChecklistElementContextDto{" + "id=" + id + '}'; + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/ChecklistSeparatorContextDto.java b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/ChecklistSeparatorContextDto.java index c990961ad5f13cfaf8d2e3ea3848811f3f44056f..c5b8ade0c965faa3579d62d477237865706f140d 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/ChecklistSeparatorContextDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/ChecklistSeparatorContextDto.java @@ -44,4 +44,9 @@ public class ChecklistSeparatorContextDto extends ChecklistElementContextDto { public int hashCode() { return Objects.hash(super.hashCode(), title); } + + @Override + public String toString() { + return "ChecklistSeparatorContextDto{" + "title='" + title + '\'' + "} " + super.toString(); + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistCheckboxContextDto.java b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistCheckboxContextDto.java index c49fadc795ea766f578d3834eb66d0ddf04f34e0..af9f7b51f49590e5df242610e9c85e9c99f0e658 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistCheckboxContextDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistCheckboxContextDto.java @@ -43,4 +43,17 @@ public class ChecklistCheckboxContextDto extends ChecklistFieldContextDto { public int hashCode() { return Objects.hash(super.hashCode(), textModuleTrue, textModuleFalse); } + + @Override + public String toString() { + return "ChecklistCheckboxContextDto{" + + "textModuleTrue='" + + textModuleTrue + + '\'' + + ", textModuleFalse='" + + textModuleFalse + + '\'' + + "} " + + super.toString(); + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistFieldContextDto.java b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistFieldContextDto.java index 595881c80a7c10bfc0496741c9d6be5ce44660e8..75e60a978b8dbd0c22f07a8ce1b6dc1fd4919297 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistFieldContextDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistFieldContextDto.java @@ -71,4 +71,22 @@ public abstract class ChecklistFieldContextDto extends ChecklistElementContextDt public int hashCode() { return Objects.hash(super.hashCode(), text, mandatory, note, help); } + + @Override + public String toString() { + return "ChecklistFieldContextDto{" + + "text='" + + text + + '\'' + + ", mandatory=" + + mandatory + + ", note='" + + note + + '\'' + + ", help='" + + help + + '\'' + + "} " + + super.toString(); + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistFieldOptionContextDto.java b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistFieldOptionContextDto.java index 27df235d5ad344197c8fa29e24f1fd848efc6417..da8137b2f85d315dc542d41ec6c011aa593252f1 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistFieldOptionContextDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistFieldOptionContextDto.java @@ -66,4 +66,21 @@ public class ChecklistFieldOptionContextDto { public int hashCode() { return Objects.hash(id, text, textModuleTrue, textModuleFalse); } + + @Override + public String toString() { + return "ChecklistFieldOptionContextDto{" + + "id=" + + id + + ", text='" + + text + + '\'' + + ", textModuleTrue='" + + textModuleTrue + + '\'' + + ", textModuleFalse='" + + textModuleFalse + + '\'' + + '}'; + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistOptionSelectContextDto.java b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistOptionSelectContextDto.java index 22c67390c1efb47bf1fa0f794848d5e854aebf1f..5b0dc2832238003f6878ebe8167712244272449b 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistOptionSelectContextDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklist/api/context/element/field/ChecklistOptionSelectContextDto.java @@ -36,4 +36,9 @@ public abstract class ChecklistOptionSelectContextDto extends ChecklistFieldCont public int hashCode() { return Objects.hash(super.hashCode(), items); } + + @Override + public String toString() { + return "ChecklistOptionSelectContextDto{" + "items=" + items + "} " + super.toString(); + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklist/mapper/ChecklistContextMapper.java b/backend/inspection/src/main/java/de/eshg/inspection/checklist/mapper/ChecklistContextMapper.java index 08ed792c8dfd749290fa3f03b2ede5b6ed96b2ed..fc0ac916dbe177eacb9ce63a48c9ffeeea210f5b 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklist/mapper/ChecklistContextMapper.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklist/mapper/ChecklistContextMapper.java @@ -48,13 +48,19 @@ public final class ChecklistContextMapper { context.setValidTo(version.getValidTo()); context.setExpandable(version.isExpandable()); context.setDeleted(version.isDeleted()); - context.setSections( - version.getSections().stream().map(ChecklistContextMapper::contextFrom).toList()); + context.setPublished(version.isPublished()); + context.setLastModified(version.getLastModified()); + context.setSections(contextFrom(version.getSections())); context.setRepositoryVersion(version.getRepositoryVersion()); return context; } + public static List<ChecklistSectionContextDto> contextFrom( + List<ChecklistDefinitionSection> sections) { + return sections.stream().map(ChecklistContextMapper::contextFrom).toList(); + } + public static ChecklistSectionContextDto contextFrom(ChecklistDefinitionSection section) { return contextFrom(section, true); } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionCentralRepoService.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionCentralRepoService.java index d4cf457af850a510b70867d332e8a055378e91cb..866e7808eaa7f7ac132afe648f20692a0063463e 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionCentralRepoService.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionCentralRepoService.java @@ -20,13 +20,13 @@ import com.fasterxml.jackson.core.PrettyPrinter; import com.fasterxml.jackson.core.util.MinimalPrettyPrinter; import com.fasterxml.jackson.databind.ObjectMapper; import de.eshg.centralrepository.client.CentralRepositoryRestClient; -import de.eshg.inspection.checklistdefinition.api.AddChecklistDefinitionVersionRequest; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionCentralRepoRequest; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionCentralRepoResponse; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionCentralRepoUpdateRequest; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionDto; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionFromCentralRepoUpdateRequest; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionVersionDto; +import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionVersionRequest; import de.eshg.inspection.checklistdefinition.api.CreateNewChecklistDefinitionRequest; import de.eshg.inspection.checklistdefinition.api.DeleteChecklistDefinitionCentralRepoRequest; import de.eshg.inspection.checklistdefinition.api.GetChecklistDefinitionCentralRepoRequest; @@ -100,7 +100,7 @@ public class ChecklistDefinitionCentralRepoService { UUID cldId, int cldVersionNr, ChecklistDefinitionCentralRepoRequest request) { ChecklistDefinition cld = retrieveCld(cldId); - verifyCoreChecklistAndPermission(cld.isCoreChecklist()); + validateChecklist(cld); if (cld.getMostRecentRepositoryVersion() != null) { String message = @@ -131,7 +131,7 @@ public class ChecklistDefinitionCentralRepoService { ChecklistDefinitionCentralRepoResponse updateChecklistDefinition( UUID cldId, int cldVersionNr, ChecklistDefinitionCentralRepoUpdateRequest request) { ChecklistDefinition cld = retrieveCld(cldId); - verifyCoreChecklistAndPermission(cld.isCoreChecklist()); + validateChecklist(cld); ChecklistDefinitionDto checklistDefinitionDto = prepareCentralRepoCld(cld, cldVersionNr); MetadataResponseDto metadataResponseDto = @@ -421,10 +421,11 @@ public class ChecklistDefinitionCentralRepoService { centralRepoCld.versions().getFirst().context().isExpandable(), centralRepoCld.versions().getFirst().context().isDeleted(), centralRepoCld.coreChecklist(), + centralRepoCld.published(), centralRepoCld.objectType().id(), centralRepoCld.versions().getFirst().context().getSections())); UUID localCldId = newChecklistDefinition.id(); - int localCldVersion = newChecklistDefinition.mostRecentVersionNr(); + int localCldVersion = newChecklistDefinition.mostRecentVersion().context().getVersion(); saveRepositoryVersion( localCldId, localCldVersion, request.centralRepoId(), request.centralRepoVersion()); checklistDefinitionDto = @@ -441,11 +442,12 @@ public class ChecklistDefinitionCentralRepoService { verifyCentralRepositoryVersion(localCld, request.centralRepoVersion()); ChecklistDefinitionVersionDto newCldVersion = checklistDefinitionService.saveNewChecklistDefinitionVersion( - new AddChecklistDefinitionVersionRequest( + new ChecklistDefinitionVersionRequest( centralRepoCld.name(), centralRepoCld.versions().getFirst().context().getDescription(), centralRepoCld.versions().getFirst().context().isExpandable(), centralRepoCld.versions().getFirst().context().isDeleted(), + centralRepoCld.versions().getFirst().context().isPublished(), centralRepoCld.versions().getFirst().context().getSections()), localCld); UUID localCldId = localCld.getExternalId(); @@ -536,8 +538,12 @@ public class ChecklistDefinitionCentralRepoService { localCld.setMostRecentVersionBasedOnRepo(null); } - private static void verifyCoreChecklistAndPermission(boolean isCoreChecklist) { - if (isCoreChecklist + private static void validateChecklist(ChecklistDefinition definition) { + if (!definition.isPublished()) { + throw new BadRequestException( + "Can not push an unpublished checklist definition to central repository"); + } + if (definition.isCoreChecklist() && currentUserHasNoRole(INSPECTION_CENTRALREPOSITORY_WRITE_CORECHECKLISTS)) { throw new BadRequestException( INSUFFICIENT_USER_RIGHTS, diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionController.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionController.java index 3845ed7747e123255c20e3f80aa59e97f56e9f7d..d13ebf147823630fe6fa033f0fee443920222ed0 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionController.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionController.java @@ -5,9 +5,9 @@ package de.eshg.inspection.checklistdefinition; -import de.eshg.inspection.checklistdefinition.api.AddChecklistDefinitionVersionRequest; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionDto; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionVersionDto; +import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionVersionRequest; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionsResponse; import de.eshg.inspection.checklistdefinition.api.CreateNewChecklistDefinitionRequest; import de.eshg.rest.service.security.config.BaseUrls; @@ -78,8 +78,16 @@ public class ChecklistDefinitionController { @Transactional() @NotNull public ChecklistDefinitionVersionDto addChecklistDefinitionVersion( - @PathVariable("id") UUID id, - @Valid @RequestBody AddChecklistDefinitionVersionRequest request) { + @PathVariable("id") UUID id, @Valid @RequestBody ChecklistDefinitionVersionRequest request) { return checklistDefinitionService.addChecklistDefinitionVersion(id, request); } + + @PutMapping(path = "/versions/{id}") + @Operation(summary = "Edits an existing checklist definition version in draft mode") + @Transactional() + @NotNull + public ChecklistDefinitionVersionDto editDraftChecklistDefinitionVersion( + @PathVariable("id") UUID id, @Valid @RequestBody ChecklistDefinitionVersionRequest request) { + return checklistDefinitionService.editDraftChecklistDefinitionVersion(id, request); + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionService.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionService.java index 78551e53d0413a9c540d1124aa9d9ce0245166ee..b3f7750aebdecb8f54bf2fe9056e573ef443fa8b 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionService.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/ChecklistDefinitionService.java @@ -5,17 +5,17 @@ package de.eshg.inspection.checklistdefinition; +import static de.eshg.inspection.checklistdefinition.mapper.ChecklistDefinitionEntityMapper.getLatestVersion; import static de.eshg.lib.keycloak.EmployeePermissionRole.INSPECTION_CORECHECKLISTDEFINITIONS_EDIT; import static de.eshg.rest.service.error.ErrorCode.INSUFFICIENT_USER_RIGHTS; import static de.eshg.rest.service.security.CurrentUserHelper.currentUserHasNoRole; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; -import static java.time.temporal.ChronoUnit.SECONDS; import de.eshg.base.user.api.UserDto; -import de.eshg.inspection.checklistdefinition.api.AddChecklistDefinitionVersionRequest; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionDto; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionVersionDto; +import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionVersionRequest; import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionsResponse; import de.eshg.inspection.checklistdefinition.api.CreateNewChecklistDefinitionRequest; import de.eshg.inspection.checklistdefinition.mapper.ChecklistDefinitionDtoMapper; @@ -28,9 +28,9 @@ import de.eshg.inspection.client.UserClient; import de.eshg.rest.service.error.BadRequestException; import de.eshg.rest.service.error.NotFoundException; import java.time.Clock; -import java.time.Instant; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -65,7 +65,9 @@ public class ChecklistDefinitionService { checklistDefinitionRepository.findAll().stream() .sorted( (cld1, cld2) -> { - int deletedComparison = Boolean.compare(cld1.isDeleted(), cld2.isDeleted()); + int deletedComparison = + Boolean.compare( + getLatestVersion(cld1).isDeleted(), getLatestVersion(cld2).isDeleted()); if (deletedComparison != 0) { return deletedComparison; } @@ -129,7 +131,7 @@ public class ChecklistDefinitionService { } ChecklistDefinitionDto saveNewChecklistDefinition(CreateNewChecklistDefinitionRequest request) { - ChecklistDefinition entity = mapper.entityFrom(request); + ChecklistDefinition entity = mapper.newEntityFrom(request); ChecklistDefinition saved = checklistDefinitionRepository.saveAndFlush(entity); Map<UUID, UserDto> users; try { @@ -143,41 +145,58 @@ public class ChecklistDefinitionService { } public ChecklistDefinitionVersionDto addChecklistDefinitionVersion( - UUID id, AddChecklistDefinitionVersionRequest request) { + UUID defId, ChecklistDefinitionVersionRequest request) { ChecklistDefinition dbDefinition = checklistDefinitionRepository - .findById(id) + .findById(defId) .orElseThrow(() -> new NotFoundException("ChecklistDefinition")); - // check if user tried to modify a core checklist but has no rights for that - if (dbDefinition.isCoreChecklist() && mayNotEditCoreChecklists()) { - throw new BadRequestException(INSUFFICIENT_USER_RIGHTS, "no rights to edit core checklists"); + checkUserRightsForCldVersionRequest(dbDefinition, request); + if (!getLatestVersion(dbDefinition).isPublished()) { + throw new BadRequestException( + "Can not create a new version if an existing unpublished version exists."); } - // check if user requested isExpandable=false but has no rights for that - if (request.isExpandable() != null && request.isExpandable().equals(FALSE)) { - if (mayNotEditCoreChecklists()) { - throw new BadRequestException( - INSUFFICIENT_USER_RIGHTS, "no rights to mark a checklist as non-expandable"); - } - if (!dbDefinition.isCoreChecklist()) { - throw new BadRequestException( - "setting a version to non-expandable is only allowed for core checklists"); - } + return saveNewChecklistDefinitionVersion(request, dbDefinition); + } + + public ChecklistDefinitionVersionDto editDraftChecklistDefinitionVersion( + UUID versionId, ChecklistDefinitionVersionRequest request) { + ChecklistDefinitionVersion dbVersion = + checklistDefinitionVersionRepository + .findById(versionId) + .orElseThrow(() -> new NotFoundException("ChecklistDefinitionVersion")); + ChecklistDefinition dbDefinition = dbVersion.getChecklistDefinition(); + + if (dbVersion.isPublished()) { + throw new BadRequestException( + "This version can not be edited, because it is already published."); + } else if (dbVersion.getId() != getLatestVersion(dbDefinition).getId()) { + throw new IllegalStateException( + "This version can not be edited, because it is not the newest draft version."); } - return saveNewChecklistDefinitionVersion(request, dbDefinition); + checkUserRightsForCldVersionRequest(dbDefinition, request); + + ChecklistDefinitionVersion editedVersionEntity = mapper.editEntityFrom(request, dbVersion); + + ChecklistDefinitionVersion savedVersion = + checklistDefinitionVersionRepository.save(editedVersionEntity); + + return ChecklistDefinitionDtoMapper.dtoFrom( + savedVersion, userClient.getUserById(savedVersion.getModifiedBy())); } ChecklistDefinitionVersionDto saveNewChecklistDefinitionVersion( - AddChecklistDefinitionVersionRequest request, ChecklistDefinition dbDefinition) { - // versions are sorted by ascending version number, so the last element has the highest version - ChecklistDefinitionVersion latestVersion = dbDefinition.getVersions().getLast(); + ChecklistDefinitionVersionRequest request, ChecklistDefinition dbDefinition) { + ChecklistDefinitionVersion latestVersion = getLatestVersion(dbDefinition); - latestVersion.setValidTo(Instant.now(clock).truncatedTo(SECONDS)); + if (Optional.ofNullable(request.published()).orElse(true)) { + latestVersion.setValidTo(clock.instant()); + } ChecklistDefinitionVersion newVersionEntity = - mapper.entityFrom(request, dbDefinition, latestVersion.getVersion() + 1); + mapper.newEntityFrom(request, dbDefinition, latestVersion.getVersion() + 1); ChecklistDefinitionVersion savedVersion = checklistDefinitionVersionRepository.save(newVersionEntity); @@ -186,6 +205,26 @@ public class ChecklistDefinitionService { savedVersion, userClient.getUserById(savedVersion.getModifiedBy())); } + private static void checkUserRightsForCldVersionRequest( + ChecklistDefinition dbDefinition, ChecklistDefinitionVersionRequest request) { + // check if user tried to modify a core checklist but has no rights for that + if (dbDefinition.isCoreChecklist() && mayNotEditCoreChecklists()) { + throw new BadRequestException(INSUFFICIENT_USER_RIGHTS, "no rights to edit core checklists"); + } + + // check if user requested isExpandable=false but has no rights for that + if (request.isExpandable() != null && request.isExpandable().equals(FALSE)) { + if (mayNotEditCoreChecklists()) { + throw new BadRequestException( + INSUFFICIENT_USER_RIGHTS, "no rights to mark a checklist as non-expandable"); + } + if (!dbDefinition.isCoreChecklist()) { + throw new BadRequestException( + "setting a version to non-expandable is only allowed for core checklists"); + } + } + } + private static boolean mayNotEditCoreChecklists() { return currentUserHasNoRole(INSPECTION_CORECHECKLISTDEFINITIONS_EDIT); } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionDto.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionDto.java index 41844063f6e4e085a7e4aa4b1ada798e0c7bc5ae..82d4fc5eb0c16962c1cc98dac0f7083b5274e693 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionDto.java @@ -9,6 +9,7 @@ import de.eshg.inspection.objecttype.api.ObjectTypeRefDto; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; +import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -18,24 +19,28 @@ public record ChecklistDefinitionDto( @NotNull UUID id, @NotNull String name, @NotNull boolean coreChecklist, - @NotNull UUID mostRecentVersionId, - @NotNull int mostRecentVersionNr, + @NotNull boolean expandable, // depends on coreChecklist Integer mostRecentRepositoryVersion, Integer mostRecentVersionBasedOnRepo, @Valid ObjectTypeRefDto objectType, @NotNull boolean deleted, + @NotNull boolean published, + @NotNull Instant lastModified, + @Valid @NotNull ChecklistDefinitionVersionDto mostRecentVersion, @Valid @NotNull List<ChecklistDefinitionVersionDto> versions) { - public ChecklistDefinitionDto withoutVersion() { + public ChecklistDefinitionDto withoutVersions() { return new ChecklistDefinitionDto( id, name, coreChecklist, - mostRecentVersionId, - mostRecentVersionNr, + expandable, null, null, objectType, deleted, + published, + lastModified, + null, new ArrayList<>()); } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionVersionDto.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionVersionDto.java index 916b65d8795ca2b52a5219e7efb829e6aee40426..05e5716422e2c0f6f4b37956a0330f3cff648c02 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionVersionDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionVersionDto.java @@ -17,4 +17,5 @@ public record ChecklistDefinitionVersionDto( @NotNull @Valid ChecklistContextDto context, @Valid UserDto modifiedBy, @Valid ObjectTypeRefDto objectType, - Boolean isCoreChecklist) {} + Boolean isCoreChecklist, + Boolean hasDraft) {} diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/AddChecklistDefinitionVersionRequest.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionVersionRequest.java similarity index 82% rename from backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/AddChecklistDefinitionVersionRequest.java rename to backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionVersionRequest.java index 9b28dd7efc3573c0d2224db407912a9198449cca..e80c68f686460c60b37399048b472421650053b0 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/AddChecklistDefinitionVersionRequest.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/ChecklistDefinitionVersionRequest.java @@ -12,10 +12,11 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import java.util.List; -@Schema(name = "AddChecklistDefinitionVersionRequest") -public record AddChecklistDefinitionVersionRequest( +@Schema(name = "ChecklistDefinitionVersionRequest") +public record ChecklistDefinitionVersionRequest( @NotBlank String name, String description, Boolean isExpandable, Boolean deleted, + Boolean published, @NotNull @Valid List<ChecklistSectionContextDto> sections) {} diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/CreateNewChecklistDefinitionRequest.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/CreateNewChecklistDefinitionRequest.java index 7b9ab6ec24d77aab003c8511e02747b3dc6a2581..2e4e788c9af35d298d601b2d177c7ba6854ad467 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/CreateNewChecklistDefinitionRequest.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/api/CreateNewChecklistDefinitionRequest.java @@ -20,16 +20,31 @@ public record CreateNewChecklistDefinitionRequest( Boolean isExpandable, Boolean deleted, Boolean isCoreChecklist, + Boolean published, @NotNull UUID objectTypeId, @NotNull @Valid List<ChecklistSectionContextDto> sections) { public CreateNewChecklistDefinitionRequest withObjectTypeId(@NotNull UUID objectTypeId) { return new CreateNewChecklistDefinitionRequest( - name, description, isExpandable, deleted, isCoreChecklist, objectTypeId, sections); + name, + description, + isExpandable, + deleted, + isCoreChecklist, + published, + objectTypeId, + sections); } public CreateNewChecklistDefinitionRequest withName(@NotBlank String name) { return new CreateNewChecklistDefinitionRequest( - name, description, isExpandable, deleted, isCoreChecklist, objectTypeId, sections); + name, + description, + isExpandable, + deleted, + isCoreChecklist, + published, + objectTypeId, + sections); } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/CentralRepositoryMapper.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/CentralRepositoryMapper.java index 7502bd96d67fbb21a645ee4b0abde17354e9f186..d9038d6f4d42a6b9044b1eb1cce3acf661daae79 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/CentralRepositoryMapper.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/CentralRepositoryMapper.java @@ -149,12 +149,19 @@ public final class CentralRepositoryMapper { centralRepoCld.id(), centralRepoCld.name(), centralRepoCld.coreChecklist(), - centralRepoCld.mostRecentVersionId(), - centralRepoCld.mostRecentVersionNr(), + centralRepoCld.expandable(), centralRepoCld.mostRecentRepositoryVersion(), centralRepoCld.mostRecentVersionBasedOnRepo(), new ObjectTypeRefDto(localObjectType.getId(), localObjectType.getName()), centralRepoCld.deleted(), + centralRepoCld.published(), + centralRepoCld.lastModified(), + new ChecklistDefinitionVersionDto( + centralRepoCld.mostRecentVersion().context(), + centralRepoCld.mostRecentVersion().modifiedBy(), + new ObjectTypeRefDto(localObjectType.getId(), localObjectType.getName()), + centralRepoCld.mostRecentVersion().isCoreChecklist(), + false), centralRepoCld.versions().stream() .map( v -> @@ -162,7 +169,8 @@ public final class CentralRepositoryMapper { v.context(), v.modifiedBy(), new ObjectTypeRefDto(localObjectType.getId(), localObjectType.getName()), - v.isCoreChecklist())) + v.isCoreChecklist(), + false)) .toList()); } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/ChecklistDefinitionDtoMapper.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/ChecklistDefinitionDtoMapper.java index 51425d03410fc3c21fd2196a5c2aa0f4f6dbd7cd..0e817aee6ae7d9dce1565e2ed74b295c73b605fc 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/ChecklistDefinitionDtoMapper.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/ChecklistDefinitionDtoMapper.java @@ -6,6 +6,7 @@ package de.eshg.inspection.checklistdefinition.mapper; import static de.eshg.inspection.checklist.mapper.ChecklistContextMapper.contextFrom; +import static de.eshg.inspection.checklistdefinition.mapper.ChecklistDefinitionEntityMapper.getLatestVersion; import static java.util.Optional.ofNullable; import de.eshg.base.user.api.UserDto; @@ -17,6 +18,7 @@ import de.eshg.inspection.objecttype.api.ObjectTypeRefDto; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.SortedSet; import java.util.UUID; @@ -34,8 +36,8 @@ public final class ChecklistDefinitionDtoMapper { // it's dull to load all versions just to retrieve the ID of the last one -- maybe can be // optimized later List<ChecklistDefinitionVersion> versions = entity.getVersions(); - UUID mostRecentVersionID = versions.getLast().getId(); - int mostRecentVersionNr = versions.getLast().getVersion(); + var latestVersion = getLatestVersion(entity); + boolean isExpandable = latestVersion.isExpandable(); List<ChecklistDefinitionVersionDto> dtoVersions = new ArrayList<>(); @@ -54,12 +56,18 @@ public final class ChecklistDefinitionDtoMapper { entity.getId(), entity.getName(), entity.isCoreChecklist(), - mostRecentVersionID, - mostRecentVersionNr, + isExpandable, isCentralRepoDto ? null : entity.getMostRecentRepositoryVersion(), isCentralRepoDto ? null : entity.getMostRecentVersionBasedOnRepo(), dtoObjectTypeFrom(entity), entity.isDeleted(), + entity.isPublished(), + entity.getVersions().getLast().getLastModified(), + dtoFrom( + latestVersion, + Optional.ofNullable(users) + .map(usrs -> usrs.get(latestVersion.getModifiedBy())) + .orElse(null)), dtoVersions); } @@ -79,6 +87,7 @@ public final class ChecklistDefinitionDtoMapper { contextFrom(version), modifiedByUser, dtoObjectTypeFrom(version.getChecklistDefinition()), - version.getChecklistDefinition().isCoreChecklist()); + version.getChecklistDefinition().isCoreChecklist(), + !version.getChecklistDefinition().isPublished()); } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/ChecklistDefinitionEntityMapper.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/ChecklistDefinitionEntityMapper.java index 83e18d414ad00ef085a8817caa2c4b50d93e93ed..9f8f8373e2fb2c8c2d1ecfe3ca9ed640fc6b4f2e 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/ChecklistDefinitionEntityMapper.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/mapper/ChecklistDefinitionEntityMapper.java @@ -5,8 +5,6 @@ package de.eshg.inspection.checklistdefinition.mapper; -import static java.time.temporal.ChronoUnit.SECONDS; - import de.eshg.inspection.checklist.api.context.ChecklistSectionContextDto; import de.eshg.inspection.checklist.api.context.element.ChecklistSeparatorContextDto; import de.eshg.inspection.checklist.api.context.element.field.ChecklistAudioContextDto; @@ -17,7 +15,7 @@ import de.eshg.inspection.checklist.api.context.element.field.ChecklistImageCont import de.eshg.inspection.checklist.api.context.element.field.ChecklistMultiSelectContextDto; import de.eshg.inspection.checklist.api.context.element.field.ChecklistSingleSelectContextDto; import de.eshg.inspection.checklist.api.context.element.field.ChecklistTextElementContextDto; -import de.eshg.inspection.checklistdefinition.api.AddChecklistDefinitionVersionRequest; +import de.eshg.inspection.checklistdefinition.api.ChecklistDefinitionVersionRequest; import de.eshg.inspection.checklistdefinition.api.CreateNewChecklistDefinitionRequest; import de.eshg.inspection.checklistdefinition.persistence.ChecklistDefinition; import de.eshg.inspection.checklistdefinition.persistence.ChecklistDefinitionVersion; @@ -56,51 +54,112 @@ public class ChecklistDefinitionEntityMapper { this.clock = clock; } - public ChecklistDefinition entityFrom(CreateNewChecklistDefinitionRequest request) { + public ChecklistDefinition newEntityFrom(CreateNewChecklistDefinitionRequest request) { + boolean published = Optional.ofNullable(request.published()).orElse(true); + boolean deleted = Optional.ofNullable(request.deleted()).orElse(false); + ChecklistDefinition definition = new ChecklistDefinition(); definition.setCoreChecklist(Boolean.TRUE.equals(request.isCoreChecklist())); ObjectType objectType = findObjectType(request.objectTypeId()); definition.getObjectTypes().add(objectType); ChecklistDefinitionVersion version = new ChecklistDefinitionVersion(); - version.setValidFrom(Instant.now(clock).truncatedTo(SECONDS)); - version.setValidTo(null); version.setVersion(1); version.setName(request.name()); version.setDescription(request.description()); version.setModifiedBy(CurrentUserHelper.getCurrentUserId()); - version.setDeleted(Optional.ofNullable(request.deleted()).orElse(false)); + version.setDeleted(deleted); + version.setPublished(published); request.sections().forEach((section -> version.addSection(entitySectionFrom(section)))); - definition.addNewVersion(version); // also sets version.name to definition + + registerNewVersion(published, deleted, definition, version); // to be able to call this, version needs to be registered to definition already version.setExpandable(Optional.ofNullable(request.isExpandable()).orElse(true)); + version.setLastModified(clock.instant()); + return definition; } - public ChecklistDefinitionVersion entityFrom( - AddChecklistDefinitionVersionRequest request, - ChecklistDefinition definition, - int newVersion) { + public ChecklistDefinitionVersion newEntityFrom( + ChecklistDefinitionVersionRequest request, ChecklistDefinition definition, int newVersion) { + boolean published = Optional.ofNullable(request.published()).orElse(true); + boolean deleted = Optional.ofNullable(request.deleted()).orElse(false); + ChecklistDefinitionVersion version = new ChecklistDefinitionVersion(); version.setName(request.name()); version.setDescription(request.description()); version.setVersion(newVersion); - version.setValidFrom(Instant.now(clock).truncatedTo(SECONDS)); - version.setValidTo(null); version.setModifiedBy(CurrentUserHelper.getCurrentUserId()); + version.setPublished(published); version.setDeleted(Optional.ofNullable(request.deleted()).orElse(false)); request.sections().forEach(section -> version.addSection(entitySectionFrom(section))); - definition.addNewVersion(version); // also sets version.name & version.deleted to definition + registerNewVersion(published, deleted, definition, version); + + // to be able to call this, version needs to be registered to definition already + version.setExpandable(Optional.ofNullable(request.isExpandable()).orElse(true)); + + version.setLastModified(clock.instant()); + + return version; + } + + public ChecklistDefinitionVersion editEntityFrom( + ChecklistDefinitionVersionRequest request, ChecklistDefinitionVersion version) { + boolean published = Optional.ofNullable(request.published()).orElse(true); + boolean deleted = Optional.ofNullable(request.deleted()).orElse(false); + Instant now = clock.instant(); + + version.setName(request.name()); + version.setDescription(request.description()); + version.setModifiedBy(CurrentUserHelper.getCurrentUserId()); + version.setPublished(published); + version.setDeleted(deleted); + version.getSections().clear(); + request.sections().forEach(section -> version.addSection(entitySectionFrom(section))); + if (published) { + version.setValidTo(null); + version.setValidFrom(now); + ChecklistDefinition cld = version.getChecklistDefinition(); + cld.setPublished(true); + cld.setDeleted(deleted); + if (cld.getVersions().size() >= 2) { + ChecklistDefinitionVersion prev = cld.getVersions().get(cld.getVersions().size() - 2); + prev.setValidTo(now); + } + } // to be able to call this, version needs to be registered to definition already version.setExpandable(Optional.ofNullable(request.isExpandable()).orElse(true)); + version.setLastModified(now); + return version; } + private void registerNewVersion( + boolean published, + boolean deleted, + ChecklistDefinition definition, + ChecklistDefinitionVersion version) { + Instant now = clock.instant(); + if (published) { + version.setValidFrom(now); + version.setValidTo(null); + definition.setDeleted(deleted); + if (!definition.getVersions().isEmpty()) { + getLatestVersion(definition).setValidTo(now); + } + } else { + version.setValidFrom(null); + version.setValidTo(null); + } + definition.setPublished(published); + definition.addNewVersion(version); // also sets version.name to definition + } + private ChecklistDefinitionSection entitySectionFrom(ChecklistSectionContextDto section) { ChecklistDefinitionSection entitySection = new ChecklistDefinitionSection(); entitySection.setTitle(section.getTitle()); @@ -198,4 +257,10 @@ public class ChecklistDefinitionEntityMapper { } throw new BadRequestException("missing objectTypeId"); } + + public static ChecklistDefinitionVersion getLatestVersion( + ChecklistDefinition checklistDefinition) { + // versions are sorted by ascending version number, so the last element has the highest version + return checklistDefinition.getVersions().getLast(); + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinition.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinition.java index 1601715652b57926831f66b7398c4f4fea387167..8a73f23c86e93c9ea9c27fb7383aacbb61fd0460 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinition.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinition.java @@ -87,6 +87,17 @@ public class ChecklistDefinition extends GloballyUniqueEntityBase { @DataSensitivity(SensitivityLevel.PUBLIC) private boolean deleted; + /** + * If a checklist definition version has published = false, this CLD is considered in draft state + * * + * + * <p>The current state is set by the most recent version. + */ + @Column(nullable = false) + @ColumnDefault("true") + @DataSensitivity(SensitivityLevel.PUBLIC) + private boolean published; + public String getName() { return name; } @@ -129,7 +140,6 @@ public class ChecklistDefinition extends GloballyUniqueEntityBase { public void addNewVersion(ChecklistDefinitionVersion version) { name = version.getName(); - deleted = version.isDeleted(); version.setChecklistDefinition(this); versions.add(version); } @@ -145,4 +155,16 @@ public class ChecklistDefinition extends GloballyUniqueEntityBase { public boolean isDeleted() { return deleted; } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + public boolean isPublished() { + return published; + } + + public void setPublished(boolean published) { + this.published = published; + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinitionVersion.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinitionVersion.java index 8e9032e832c22e5b93ee9108a4ca4f999f3049bd..9b77b1202dfa88a0b5014bf4ce99cbb275800e6f 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinitionVersion.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinitionVersion.java @@ -20,8 +20,11 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OrderBy; +import jakarta.persistence.PrePersist; +import jakarta.persistence.PreUpdate; import jakarta.persistence.Table; import jakarta.persistence.UniqueConstraint; +import jakarta.validation.ConstraintViolationException; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotNull; import java.time.Instant; @@ -29,6 +32,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.hibernate.annotations.ColumnDefault; +import org.springframework.data.annotation.LastModifiedDate; @Entity @Table( @@ -50,8 +54,7 @@ public class ChecklistDefinitionVersion { @DataSensitivity(SensitivityLevel.PUBLIC) private String description; - @Column(nullable = false) - @NotNull + @Column() @DataSensitivity(SensitivityLevel.PUBLIC) private Instant validFrom; @@ -82,11 +85,17 @@ public class ChecklistDefinitionVersion { @DataSensitivity(SensitivityLevel.PUBLIC) private boolean isExpandable = true; + @Column(nullable = false) + @NotNull + @DataSensitivity(SensitivityLevel.PUBLIC) + @LastModifiedDate + private Instant lastModified; + @NotNull @OneToMany( fetch = FetchType.LAZY, mappedBy = ChecklistDefinitionSection_.CHECKLIST_DEFINITION_VERSION, - cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, + cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, orphanRemoval = true) @OrderBy(ChecklistDefinitionSection_.POSITION) @DataSensitivity(SensitivityLevel.PUBLIC) @@ -107,6 +116,15 @@ public class ChecklistDefinitionVersion { @DataSensitivity(SensitivityLevel.PUBLIC) private boolean deleted = false; + /** + * If a checklist definition version has published = false, this CLD is considered in published + * state + */ + @Column(nullable = false) + @ColumnDefault("true") + @DataSensitivity(SensitivityLevel.PUBLIC) + private boolean published = true; + public UUID getId() { return id; } @@ -183,6 +201,14 @@ public class ChecklistDefinitionVersion { isExpandable = expandable; } + public @NotNull Instant getLastModified() { + return lastModified; + } + + public void setLastModified(@NotNull Instant lastModified) { + this.lastModified = lastModified; + } + public List<ChecklistDefinitionSection> getSections() { return sections; } @@ -208,4 +234,21 @@ public class ChecklistDefinitionVersion { public void setDeleted(boolean deleted) { this.deleted = deleted; } + + public boolean isPublished() { + return published; + } + + public void setPublished(boolean draft) { + this.published = draft; + } + + @PrePersist + @PreUpdate + private void validate() { + if (this.validFrom == null && this.published) { + throw new ConstraintViolationException( + "validFrom can not be null for published checklist definition versions", null); + } + } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinitionVersionRepository.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinitionVersionRepository.java index a19a768f91fb81ef373e7bf4ffb16d3b3a328ff2..1602c85306d3053369abdb520444784d29e7ef7a 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinitionVersionRepository.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/ChecklistDefinitionVersionRepository.java @@ -27,6 +27,7 @@ public interface ChecklistDefinitionVersionRepository select v from ChecklistDefinitionVersion v where v.validTo is null + and v.published = true and :objectType member of v.checklistDefinition.objectTypes and v.checklistDefinition.deleted = false order by v.name, v.validFrom desc @@ -48,6 +49,7 @@ public interface ChecklistDefinitionVersionRepository select v from ChecklistDefinitionVersion v where v.validTo is null + and v.published = true and :objectType member of v.checklistDefinition.objectTypes and v.checklistDefinition.id not in :excludedChecklistDefinitionIds and v.checklistDefinition.deleted = false @@ -67,6 +69,7 @@ public interface ChecklistDefinitionVersionRepository select v from ChecklistDefinitionVersion v where v.validTo is null + and v.published = true and v.checklistDefinition.isCoreChecklist = true and v.checklistDefinition.deleted = false and :objectType member of v.checklistDefinition.objectTypes diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/section/ChecklistDefinitionSection.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/section/ChecklistDefinitionSection.java index 213b38fe3b054fc12d6fa0e240c187b52a89d292..6fce1f89e6cd3e36bda5df3bf2b650078a7dac24 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/section/ChecklistDefinitionSection.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/section/ChecklistDefinitionSection.java @@ -38,7 +38,7 @@ public class ChecklistDefinitionSection extends GloballyUniqueEntityBase { @OneToMany( fetch = FetchType.LAZY, mappedBy = ChecklistDefinitionElement_.CHECKLIST_DEFINITION_SECTION, - cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, + cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, orphanRemoval = true) @OrderBy(ChecklistDefinitionElement_.POSITION) @DataSensitivity(SensitivityLevel.PUBLIC) diff --git a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/section/element/field/ChecklistDefinitionOptionSelect.java b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/section/element/field/ChecklistDefinitionOptionSelect.java index 000e99f0534808f30b2c60c5822d923f92acfc0e..f040940122155eb82c795a123646a2be1786a017 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/section/element/field/ChecklistDefinitionOptionSelect.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/checklistdefinition/persistence/section/element/field/ChecklistDefinitionOptionSelect.java @@ -21,7 +21,7 @@ public abstract class ChecklistDefinitionOptionSelect extends ChecklistDefinitio @OneToMany( fetch = FetchType.LAZY, mappedBy = ChecklistDefinitionFieldOption_.CHECKLIST_DEFINITION_ELEMENT, - cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, + cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, orphanRemoval = true) @OrderBy(ChecklistDefinitionFieldOption_.POSITION) @DataSensitivity(SensitivityLevel.PUBLIC) diff --git a/backend/inspection/src/main/java/de/eshg/inspection/facility/FacilityService.java b/backend/inspection/src/main/java/de/eshg/inspection/facility/FacilityService.java index cd039c69a752e5842a4e0a3ed83e7f6e7f894c29..9138f3a8f9f4b2110c57c991e56f19afc967473e 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/facility/FacilityService.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/facility/FacilityService.java @@ -31,6 +31,7 @@ import de.eshg.inspection.facility.persistence.PendingFacilityView; import de.eshg.inspection.facility.websearch.WebSearchService; import de.eshg.inspection.facility.websearch.persistence.WebSearchEntry; import de.eshg.inspection.facility.websearch.persistence.WebSearchEntryStatus; +import de.eshg.inspection.inspection.InspectionFinalizer; import de.eshg.inspection.inspection.InspectionService; import de.eshg.inspection.inspection.api.InspectionPhase; import de.eshg.inspection.inspection.api.InspectionType; @@ -60,6 +61,7 @@ import jakarta.persistence.criteria.Root; import java.time.Clock; import java.time.Instant; import java.time.LocalDate; +import java.time.ZoneOffset; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -87,6 +89,7 @@ public class FacilityService { private final WebSearchService webSearchService; private final Clock clock; private final EntityManager entityManager; + private final InspectionFinalizer inspectionFinalizer; public FacilityService( FacilityRepository facilityRepository, @@ -94,13 +97,15 @@ public class FacilityService { InspectionService inspectionService, WebSearchService webSearchService, Clock clock, - EntityManager entityManager) { + EntityManager entityManager, + InspectionFinalizer inspectionFinalizer) { this.facilityRepository = facilityRepository; this.facilityClient = facilityClient; this.inspectionService = inspectionService; this.webSearchService = webSearchService; this.clock = clock; this.entityManager = entityManager; + this.inspectionFinalizer = inspectionFinalizer; } public InspFacilityDto getFacility(UUID externalId) { @@ -186,6 +191,11 @@ public class FacilityService { Facility inspFacility = matchedInspFacility.get(); centralFileStateId = inspFacility.getCentralFileStateId(); newestInspection = inspectionService.findNewestOpenInspectionForFacility(inspFacility); + if (newestInspection == null) { + newestInspection = + inspectionFinalizer.createFollowupInspection( + inspectionService.findNewestClosedInspectionForFacility(inspFacility)); + } } linkWebSearchFacility(request.webSearchEntryId(), centralFileStateId); @@ -311,7 +321,13 @@ public class FacilityService { cb.isNotNull(plannedAppointmentJoin), cb.lessThanOrEqualTo( plannedAppointmentJoin.get(InspectionAppointment_.appointmentStart), - isBefore)))); + isBefore)), + cb.and( + cb.isNull(executionAppointmentJoin), + cb.isNull(plannedAppointmentJoin), + cb.lessThanOrEqualTo( + cb.literal(LocalDate.ofInstant(clock.instant(), ZoneOffset.UTC)), + LocalDate.ofInstant(isBefore, ZoneOffset.UTC))))); } if (isAfter != null) { predicates.add( @@ -325,8 +341,13 @@ public class FacilityService { cb.isNull(executionAppointmentJoin), cb.isNotNull(plannedAppointmentJoin), cb.greaterThanOrEqualTo( - plannedAppointmentJoin.get(InspectionAppointment_.appointmentEnd), - isAfter)))); + plannedAppointmentJoin.get(InspectionAppointment_.appointmentEnd), isAfter)), + cb.and( + cb.isNull(executionAppointmentJoin), + cb.isNull(plannedAppointmentJoin), + cb.greaterThanOrEqualTo( + cb.literal(LocalDate.ofInstant(clock.instant(), ZoneOffset.UTC)), + LocalDate.ofInstant(isAfter, ZoneOffset.UTC))))); } cq.select(cb.construct(PendingFacilityView.class, facilityJoin, irfJoin, inspectionRoot)); diff --git a/backend/inspection/src/main/java/de/eshg/inspection/facility/api/GetPendingFacilitiesPaginationOptionsDto.java b/backend/inspection/src/main/java/de/eshg/inspection/facility/api/GetPendingFacilitiesPaginationOptionsDto.java index 843baa7c7bafc63440e5338e63c76c8e7aba7fa2..88a6a0f1dbb50cc3a54d0b185e89d791c934bb21 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/facility/api/GetPendingFacilitiesPaginationOptionsDto.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/facility/api/GetPendingFacilitiesPaginationOptionsDto.java @@ -52,7 +52,8 @@ public record GetPendingFacilitiesPaginationOptionsDto( "objecttype_name", "inspection_status", "inspection_type", - "inspection_phase"); + "inspection_phase", + "inspection_numberOfIncidents"); } public static Comparator<InspPendingFacilityDto> createComparator(PageRequest pageRequest) { @@ -87,6 +88,10 @@ public record GetPendingFacilitiesPaginationOptionsDto( comparing( e -> e.inspection() == null ? null : e.inspection().phase(), nullsLast(naturalOrder())); + case "inspection_numberOfIncidents" -> + comparing( + e -> e.inspection() == null ? null : e.inspection().numberOfIncidents(), + nullsLast(naturalOrder())); default -> throw new BadRequestException("invalid sort param: " + order.getProperty()); }; if (order.isDescending()) { diff --git a/backend/inspection/src/main/java/de/eshg/inspection/inspection/InspectionFinalizer.java b/backend/inspection/src/main/java/de/eshg/inspection/inspection/InspectionFinalizer.java index 1e1343295fceef5647e2f62dc0440b8a119ccbc8..91a6bc86e4ab9a6fc5160249286e5758855b0161 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/inspection/InspectionFinalizer.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/inspection/InspectionFinalizer.java @@ -205,7 +205,7 @@ public class InspectionFinalizer { report.setReportFile(pdf); } - private Inspection createFollowupInspection(Inspection precedingInspection) { + public Inspection createFollowupInspection(Inspection precedingInspection) { Inspection followupInspection = new Inspection(); followupInspection.setModifiedBy(precedingInspection.getModifiedBy()); followupInspection.setPhase(InspectionPhase.NEW); @@ -227,10 +227,10 @@ public class InspectionFinalizer { if (followupType != null) { type = followupType.asInspectionType; } else { - if (precedingInspection.getType() == InspectionType.DOCUMENT_INSPECTION - || precedingInspection.getType() == InspectionType.COMPLAINT - || precedingInspection.getType() == InspectionType.REVIEW) { + if (precedingInspection.getType().isComplaint()) { type = InspectionType.REGULAR_AFTER_INCIDENTS; + } else if (InspectionResult.FAILED.equals(precedingInspection.getResult())) { + type = InspectionType.REVIEW; } else { type = InspectionType.REGULAR; } @@ -238,17 +238,25 @@ public class InspectionFinalizer { followupInspection.setType(type); // determine followup appointment - InspectionAppointment followupAppointment = computeFollowupAppointment(precedingInspection); + InspectionAppointment followupAppointment = + computeFollowupAppointment(precedingInspection, type); followupInspection.setPlannedAppointment(followupAppointment); - // create calendar event for followup appointment - UUID calenderEventId = - calendarClient.createEventInUserCalendar( - followupAppointment.getAppointmentStart(), followupAppointment.getAppointmentEnd()); - followupInspection.setCalendarEventId(calenderEventId); + // In case of new inspection after negative review + if (followupAppointment != null) { + // create calendar event for followup appointment + UUID calenderEventId = + calendarClient.createEventInUserCalendar( + followupAppointment.getAppointmentStart(), followupAppointment.getAppointmentEnd()); + followupInspection.setCalendarEventId(calenderEventId); + } // copy checklists - if (precedingInspection.getFollowupType() != null) { + if (precedingInspection.getFollowupType() != null + || + // Also copy checklist if last inspection failed and a new one is created + precedingInspection.getResult().equals(InspectionResult.FAILED) + && followupInspection.getType().equals(InspectionType.REVIEW)) { followupInspection.addChecklists( precedingInspection.getChecklists().stream().map(Checklist::getCopy).toList()); @@ -287,14 +295,18 @@ public class InspectionFinalizer { return followupInspection; } - private static InspectionAppointment computeFollowupAppointment(Inspection precedingInspection) { + private static InspectionAppointment computeFollowupAppointment( + Inspection precedingInspection, InspectionType followupInspectionType) { + if (precedingInspection.getResult().equals(InspectionResult.FAILED)) { + return null; + } ObjectType objectType = precedingInspection.getRelatedFacility().getFacility().getObjectType(); Instant followupStartDate; if (precedingInspection.getFollowupDate() != null) { followupStartDate = precedingInspection.getFollowupDate(); } else { int interval = - (precedingInspection.getType().isComplaint() || precedingInspection.isChallenging()) + (followupInspectionType == InspectionType.REGULAR_AFTER_INCIDENTS) ? objectType.getComplaintInterval() : objectType.getRoutineInterval(); Instant previousAppointmentStart = diff --git a/backend/inspection/src/main/java/de/eshg/inspection/inspection/InspectionService.java b/backend/inspection/src/main/java/de/eshg/inspection/inspection/InspectionService.java index 40af99c20f47ca79adf84131a3b3c9ef148f21d6..e0d57d817e650ebd097ea18fe4c480b1720f705a 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/inspection/InspectionService.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/inspection/InspectionService.java @@ -262,6 +262,10 @@ public class InspectionService { return inspectionRepository.findNewestOpenInspectionForFacility(facility); } + public Inspection findNewestClosedInspectionForFacility(Facility facility) { + return inspectionRepository.findNewestClosedInspectionForFacility(facility); + } + public InspectionAvailableCLDVersionsResponse getAvailableCLDs(UUID externalId) { Inspection inspection = loadInspection(externalId); ObjectType objectType = inspection.getFacility().getObjectType(); diff --git a/backend/inspection/src/main/java/de/eshg/inspection/inspection/api/InspectionType.java b/backend/inspection/src/main/java/de/eshg/inspection/inspection/api/InspectionType.java index aa76a36c171e746628e50224e10d23ec561c9ffd..9025127387ccd81bd8f23d7f12ee431c3844654a 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/inspection/api/InspectionType.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/inspection/api/InspectionType.java @@ -17,9 +17,6 @@ public enum InspectionType { DOCUMENT_INSPECTION; public boolean isComplaint() { - return this == REGULAR_AFTER_INCIDENTS - || this == REVIEW - || this == COMPLAINT - || this == DOCUMENT_INSPECTION; + return this == REVIEW || this == COMPLAINT || this == DOCUMENT_INSPECTION; } } diff --git a/backend/inspection/src/main/java/de/eshg/inspection/inspection/persistence/InspectionRepository.java b/backend/inspection/src/main/java/de/eshg/inspection/inspection/persistence/InspectionRepository.java index aad0c3a6e3dd139704843d602b3ee534af2df9db..1df6854beb47efb1a058310d1b1213b117deb1b9 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/inspection/persistence/InspectionRepository.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/inspection/persistence/InspectionRepository.java @@ -32,6 +32,21 @@ public interface InspectionRepository extends ProcedureRepository<Inspection> { """) Inspection findNewestOpenInspectionForFacility(Facility facility); + @Query( + """ + select i + from Inspection i + join InspectionRelatedFacility irf on irf.procedure = i + join Facility f on f = irf.facility + where f = :facility + and i.procedureStatus in ( + de.eshg.lib.procedure.domain.model.ProcedureStatus.CLOSED + ) + order by i.modifiedAt desc + limit 1 + """) + Inspection findNewestClosedInspectionForFacility(Facility facility); + @Query("select i from Inspection i where i.report.id = :reportId") Optional<Inspection> findByReportId(UUID reportId); diff --git a/backend/inspection/src/main/java/de/eshg/inspection/packlistdefinition/PacklistDefinitionService.java b/backend/inspection/src/main/java/de/eshg/inspection/packlistdefinition/PacklistDefinitionService.java index d6fea6da2adc0217127e42cacb7ae51fdf258ced..a184c2cdfabc60e6ab8f27ea46c6bd09998dea6e 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/packlistdefinition/PacklistDefinitionService.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/packlistdefinition/PacklistDefinitionService.java @@ -5,8 +5,6 @@ package de.eshg.inspection.packlistdefinition; -import static java.time.temporal.ChronoUnit.SECONDS; - import de.eshg.base.user.api.UserDto; import de.eshg.inspection.client.UserClient; import de.eshg.inspection.packlistdefinition.api.AddPacklistDefinitionRevisionRequest; @@ -120,7 +118,7 @@ public class PacklistDefinitionService { // revision PacklistDefinitionRevision latestRevision = dbDefinition.getRevisions().getLast(); - latestRevision.setValidTo(Instant.now(clock).truncatedTo(SECONDS)); + latestRevision.setValidTo(Instant.now(clock)); PacklistDefinitionRevision newRevisionEntity = mapper.entityFrom(request, dbDefinition, latestRevision.getRevision() + 1); diff --git a/backend/inspection/src/main/java/de/eshg/inspection/packlistdefinition/mapper/PacklistDefinitionEntityMapper.java b/backend/inspection/src/main/java/de/eshg/inspection/packlistdefinition/mapper/PacklistDefinitionEntityMapper.java index 214e97ba060f721b7cd456fb460e00ca17efdacc..69c2cc7d4a84660417b211bdac1870e25d12f750 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/packlistdefinition/mapper/PacklistDefinitionEntityMapper.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/packlistdefinition/mapper/PacklistDefinitionEntityMapper.java @@ -5,8 +5,6 @@ package de.eshg.inspection.packlistdefinition.mapper; -import static java.time.temporal.ChronoUnit.SECONDS; - import de.eshg.inspection.objecttype.persistence.ObjectType; import de.eshg.inspection.objecttype.persistence.ObjectTypeRepository; import de.eshg.inspection.packlistdefinition.api.AddPacklistDefinitionRevisionRequest; @@ -41,7 +39,7 @@ public class PacklistDefinitionEntityMapper { definition.setObjectType(objectType); PacklistDefinitionRevision revision = new PacklistDefinitionRevision(); - revision.setValidFrom(Instant.now(clock).truncatedTo(SECONDS)); + revision.setValidFrom(Instant.now(clock)); revision.setValidTo(null); revision.setRevision(1); revision.setName(request.name()); @@ -58,7 +56,7 @@ public class PacklistDefinitionEntityMapper { PacklistDefinition definition, int newRevision) { PacklistDefinitionRevision revision = new PacklistDefinitionRevision(); - revision.setValidFrom(Instant.now(clock).truncatedTo(SECONDS)); + revision.setValidFrom(Instant.now(clock)); revision.setValidTo(null); revision.setRevision(newRevision); revision.setName(request.name()); diff --git a/backend/inspection/src/main/java/de/eshg/inspection/testhelper/InspectionTestHelperController.java b/backend/inspection/src/main/java/de/eshg/inspection/testhelper/InspectionTestHelperController.java index cdf967003d15aa34079e207a634f22dc9c48a00b..6b0194a16cb581f24ccaa4d7b2a18c14a560556d 100644 --- a/backend/inspection/src/main/java/de/eshg/inspection/testhelper/InspectionTestHelperController.java +++ b/backend/inspection/src/main/java/de/eshg/inspection/testhelper/InspectionTestHelperController.java @@ -5,7 +5,7 @@ package de.eshg.inspection.testhelper; -import de.eshg.auditlog.AuditLogTestHelperApi; +import de.eshg.auditlog.SharedAuditLogTestHelperApi; import de.eshg.inspection.feature.InspectionFeature; import de.eshg.inspection.feature.InspectionFeatureToggle; import de.eshg.lib.auditlog.AuditLogTestHelperService; @@ -20,7 +20,7 @@ import org.springframework.web.service.annotation.PostExchange; @RestController @ConditionalOnTestHelperEnabled public class InspectionTestHelperController extends TestHelperController - implements AuditLogTestHelperApi { + implements SharedAuditLogTestHelperApi { private final AuditLogTestHelperService auditLogTestHelperService; private final InspectionFeatureToggle inspectionFeatureToggle; diff --git a/backend/inspection/src/main/resources/migrations/0037_cld_drafts.xml b/backend/inspection/src/main/resources/migrations/0037_cld_drafts.xml new file mode 100644 index 0000000000000000000000000000000000000000..475a5dfa622d4eca02a3c869b31f218716cfb4ae --- /dev/null +++ b/backend/inspection/src/main/resources/migrations/0037_cld_drafts.xml @@ -0,0 +1,32 @@ +<?xml version="1.1" encoding="UTF-8" standalone="no"?> +<!-- + Copyright 2024 SCOOP Software GmbH, cronn GmbH + SPDX-License-Identifier: AGPL-3.0-only +--> + +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"> + <changeSet author="GA-Lotse" id="1726236312939-2"> + <addColumn tableName="checklist_definition_version"> + <column name="last_modified" type="timestamptz" valueComputed="checklist_definition_version.valid_from"> + <constraints nullable="false"/> + </column> + </addColumn> + </changeSet> + <changeSet author="GA-Lotse" id="1726236312939-3"> + <addColumn tableName="checklist_definition"> + <column name="published" type="bool" defaultValueBoolean="true"> + <constraints nullable="false"/> + </column> + </addColumn> + </changeSet> + <changeSet author="GA-Lotse" id="1726236312939-4"> + <addColumn tableName="checklist_definition_version"> + <column name="published" type="bool" defaultValueBoolean="true"> + <constraints nullable="false"/> + </column> + </addColumn> + </changeSet> + <changeSet author="GA-Lotse" id="1726236312939-1"> + <dropNotNullConstraint columnDataType="timestamp" columnName="valid_from" tableName="checklist_definition_version"/> + </changeSet> +</databaseChangeLog> diff --git a/backend/inspection/src/main/resources/migrations/changelog.xml b/backend/inspection/src/main/resources/migrations/changelog.xml index e07f23e2715458311079ade83329c103d9e3b376..ede013484bc7d671ce26e69496b8a220ac849fd9 100644 --- a/backend/inspection/src/main/resources/migrations/changelog.xml +++ b/backend/inspection/src/main/resources/migrations/changelog.xml @@ -44,5 +44,5 @@ <include file="migrations/0034_procedure_sequences.xml"/> <include file="migrations/0035_refactor_web_search_entry_tags.xml"/> <include file="migrations/0036_inspection_notes.xml"/> - + <include file="migrations/0037_cld_drafts.xml"/> </databaseChangeLog> diff --git a/backend/keycloak-api/gradle.lockfile b/backend/keycloak-api/gradle.lockfile index 7e2436bb4adafe6236cfc3c28c83e7a3fe035a66..3ee936daf05c95b1e5e379599e863f01ddae974a 100644 --- a/backend/keycloak-api/gradle.lockfile +++ b/backend/keycloak-api/gradle.lockfile @@ -1,18 +1,18 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.woodstox:woodstox-core:6.6.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.sun.istack:istack-commons-runtime:4.1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger:swagger-annotations:1.6.14=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -62,21 +62,21 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/keycloak/Dockerfile b/backend/keycloak/Dockerfile index deef6752be2821c723acf627697ae8a80cc70d43..4c97cfa1cfa0399e70b4aee93a42f7520c4c264f 100644 --- a/backend/keycloak/Dockerfile +++ b/backend/keycloak/Dockerfile @@ -20,6 +20,7 @@ WORKDIR /opt/keycloak COPY ./keycloak-api-plain.jar ./providers/ COPY ./eshg-keycloak-plugin.jar ./providers/ +COPY ./resources/themes ./themes/ RUN /opt/keycloak/bin/kc.sh build @@ -32,8 +33,6 @@ COPY --from=keycloak-builder /opt/keycloak/ /opt/keycloak/ COPY --from=ubi-micro-build /usr/lib64/ /usr/lib64/ COPY --from=ubi-micro-build /usr/bin/curl /usr/bin/ -COPY ./resources/themes /opt/keycloak/themes/ - ENV KC_HEALTH_ENABLED true ENV KC_FEATURES_DISABLED impersonation ENV KC_DB postgres diff --git a/backend/keycloak/gradle.lockfile b/backend/keycloak/gradle.lockfile index f5a80f9f0fc8545a4dd8a412a3a7a6b1b692c1e1..213cfccab2e0d75e8c37ddd3a4114f800840a7f3 100644 --- a/backend/keycloak/gradle.lockfile +++ b/backend/keycloak/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.apicatalog:titanium-json-ld:1.3.3=compileClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath @@ -20,10 +20,10 @@ com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspat com.webauthn4j:webauthn4j-core:0.21.5.RELEASE=compileClasspath com.webauthn4j:webauthn4j-util:0.21.5.RELEASE=compileClasspath commons-codec:commons-codec:1.16.1=compileClasspath -io.micrometer:micrometer-commons:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=testCompileClasspath,testRuntimeClasspath -io.quarkus.resteasy.reactive:resteasy-reactive-common-types:3.14.4=compileClasspath -io.quarkus.resteasy.reactive:resteasy-reactive-common:3.14.4=compileClasspath +io.micrometer:micrometer-commons:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=testCompileClasspath,testRuntimeClasspath +io.quarkus.resteasy.reactive:resteasy-reactive-common-types:3.15.0=compileClasspath +io.quarkus.resteasy.reactive:resteasy-reactive-common:3.15.0=compileClasspath io.setl:rdf-urdna:1.1=compileClasspath io.smallrye.common:smallrye-common-annotation:2.6.0=compileClasspath io.smallrye.reactive:mutiny-zero-flow-adapters:1.1.0=compileClasspath @@ -73,13 +73,13 @@ org.junit.platform:junit-platform-commons:1.10.3=testCompileClasspath,testRuntim org.junit.platform:junit-platform-engine:1.10.3=testRuntimeClasspath org.junit.platform:junit-platform-launcher:1.10.3=testRuntimeClasspath org.junit:junit-bom:5.10.3=testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-common:25.0.4=compileClasspath -org.keycloak:keycloak-core:25.0.4=compileClasspath -org.keycloak:keycloak-model-storage-private:25.0.4=compileClasspath -org.keycloak:keycloak-model-storage:25.0.4=compileClasspath -org.keycloak:keycloak-server-spi-private:25.0.4=compileClasspath -org.keycloak:keycloak-server-spi:25.0.4=compileClasspath -org.keycloak:keycloak-services:25.0.4=compileClasspath +org.keycloak:keycloak-common:25.0.6=compileClasspath +org.keycloak:keycloak-core:25.0.6=compileClasspath +org.keycloak:keycloak-model-storage-private:25.0.6=compileClasspath +org.keycloak:keycloak-model-storage:25.0.6=compileClasspath +org.keycloak:keycloak-server-spi-private:25.0.6=compileClasspath +org.keycloak:keycloak-server-spi:25.0.6=compileClasspath +org.keycloak:keycloak-services:25.0.6=compileClasspath org.mockito:mockito-core:5.11.0=testCompileClasspath,testRuntimeClasspath org.mockito:mockito-junit-jupiter:5.11.0=testCompileClasspath,testRuntimeClasspath org.objenesis:objenesis:3.3=testRuntimeClasspath @@ -91,20 +91,20 @@ org.reactivestreams:reactive-streams:1.0.4=compileClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath org.twitter4j:twitter4j-core:4.1.2=compileClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath diff --git a/backend/keycloak/resources/themes/custom-keycloak/login/messages/messages_de.properties b/backend/keycloak/resources/themes/custom-keycloak/login/messages/messages_de.properties index cbdf59272a4acc47618fa00e8915e4f3af8d04ed..6d60540d5721353bc8f6316b31520e6b549296e8 100644 --- a/backend/keycloak/resources/themes/custom-keycloak/login/messages/messages_de.properties +++ b/backend/keycloak/resources/themes/custom-keycloak/login/messages/messages_de.properties @@ -15,3 +15,5 @@ noAccount=Noch keinen Account? doRegister=Jetzt registrieren emailSentMessage=<b>Anfrage erhalten</b><br>Wenn uns die E-Mail-Adresse bekannt ist, erhalten Sie eine E-Mail mit einem Link zur Vergabe eines neuen Passworts. + +logoutConfirmHeader=Hinweis: Um sicherzustellen, dass sensible Daten geschützt bleiben, müssen Sie den Browser nach erfolgreicher Abmeldung vollständig schließen. diff --git a/backend/keycloak/resources/themes/custom-keycloak/login/messages/messages_en.properties b/backend/keycloak/resources/themes/custom-keycloak/login/messages/messages_en.properties index d45b03e2d0328c26d6841ac4d2d8f78769e3ae30..1cbfe5db1728115f518b7fe3778a4fffba78d61b 100644 --- a/backend/keycloak/resources/themes/custom-keycloak/login/messages/messages_en.properties +++ b/backend/keycloak/resources/themes/custom-keycloak/login/messages/messages_en.properties @@ -9,3 +9,5 @@ accountLockedOut=Too many failed login attempts, try again in 6 hours. access-code-display-name=Access Code and Birthday access-code-help-text=Sign in by entering an access code provided to you and your birthday. + +logoutConfirmHeader=Important note: To ensure that no sensible data is revealed, you must close the browser entirely after successful logout. diff --git a/backend/lib-aggregation/gradle.lockfile b/backend/lib-aggregation/gradle.lockfile index d4cd3e1f9edbd1a80b01fb905177032ebcfc562b..b0ca0882b86cdf117bd24bf8c244f4d4e55f2e6b 100644 --- a/backend/lib-aggregation/gradle.lockfile +++ b/backend/lib-aggregation/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -35,17 +36,17 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testFixturesRuntimeClasspath,t com.tngtech.archunit:archunit-junit5:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testFixturesRuntimeClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -53,14 +54,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -80,10 +80,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath @@ -99,7 +99,7 @@ org.hamcrest:hamcrest-core:2.2=testFixturesRuntimeClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -124,30 +124,30 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testFixturesCompileClasspat org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testFixturesRuntimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testFixturesRuntimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testFixturesRuntimeClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -155,16 +155,16 @@ org.springframework.security:spring-security-oauth2-core:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath diff --git a/backend/lib-appointmentblock/gradle.lockfile b/backend/lib-appointmentblock/gradle.lockfile index 232c8e4cc147de05d1392bd8b6bc313b9e821af4..3e95796a9e2481ae9f527b85745c75689b565968 100644 --- a/backend/lib-appointmentblock/gradle.lockfile +++ b/backend/lib-appointmentblock/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -37,8 +38,8 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -46,11 +47,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -58,14 +59,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -88,10 +88,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -108,9 +108,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -137,7 +137,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -145,29 +145,29 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -176,19 +176,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath diff --git a/backend/lib-auditlog/gradle.lockfile b/backend/lib-auditlog/gradle.lockfile index 17c16625d7b5a8b0f090b50b0f33ae5fb13f4b92..1507c98be7f288b24869b1e502fbfa7b25d8b6f9 100644 --- a/backend/lib-auditlog/gradle.lockfile +++ b/backend/lib-auditlog/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=productionRuntimeClasspath,runti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -38,17 +39,17 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=testRuntimeClasspath @@ -56,14 +57,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -83,10 +83,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath @@ -102,7 +102,7 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -127,7 +127,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -135,26 +135,26 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -164,16 +164,16 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=productionRuntime org.springframework.security:spring-security-oauth2-resource-server:6.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.19.8=testCompileClasspath,testRuntimeClasspath org.webjars:swagger-ui:5.17.14=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath diff --git a/backend/lib-auditlog/src/main/java/de/eshg/lib/auditlog/AuditLogTestHelperService.java b/backend/lib-auditlog/src/main/java/de/eshg/lib/auditlog/AuditLogTestHelperService.java index 0e510202127c2ac7ab9f6d4d87b9a2dfab8b4586..28a8e3e323f9b401f575c7ca57866cea384b1bae 100644 --- a/backend/lib-auditlog/src/main/java/de/eshg/lib/auditlog/AuditLogTestHelperService.java +++ b/backend/lib-auditlog/src/main/java/de/eshg/lib/auditlog/AuditLogTestHelperService.java @@ -5,7 +5,7 @@ package de.eshg.lib.auditlog; -import de.eshg.auditlog.AuditLogTestHelperApi; +import de.eshg.auditlog.SharedAuditLogTestHelperApi; import de.eshg.lib.auditlog.config.AuditLogConfig; import de.eshg.testhelper.ConditionalOnTestHelperEnabled; import java.io.IOException; @@ -17,7 +17,7 @@ import org.springframework.stereotype.Service; @ConditionalOnTestHelperEnabled @Service -public class AuditLogTestHelperService implements AuditLogTestHelperApi { +public class AuditLogTestHelperService implements SharedAuditLogTestHelperApi { private static final Logger log = LoggerFactory.getLogger(AuditLogTestHelperService.class); diff --git a/backend/lib-base-client/gradle.lockfile b/backend/lib-base-client/gradle.lockfile index 3767ae6eaf30248c88ce47e166248291588a6fed..b02fddd0460949693714d81f9a77cbc99d2c1852 100644 --- a/backend/lib-base-client/gradle.lockfile +++ b/backend/lib-base-client/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -15,26 +15,26 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=productionRuntimeClasspath,runti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.nimbusds:nimbus-jose-jwt:9.37.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.sun.istack:istack-commons-runtime:4.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -50,8 +50,8 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath @@ -62,7 +62,7 @@ org.glassfish.jaxb:jaxb-runtime:4.0.5=productionRuntimeClasspath,runtimeClasspat org.glassfish.jaxb:txw2:4.0.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt @@ -87,29 +87,29 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-core:6.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-jose:6.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-resource-server:6.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.zalando:faux-pas:0.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath diff --git a/backend/lib-calendar-api/gradle.lockfile b/backend/lib-calendar-api/gradle.lockfile index 3e056dc89bca797279e5ddb421ad894e9f7d4041..c8506e1086b599764c7cc8a38a41d2f91e90c6ac 100644 --- a/backend/lib-calendar-api/gradle.lockfile +++ b/backend/lib-calendar-api/gradle.lockfile @@ -1,15 +1,15 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -46,21 +46,21 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-calendar/gradle.lockfile b/backend/lib-calendar/gradle.lockfile index 2bf8bb3349ab77cf2121c2b4801b37ad3bff7131..c60d9a48891923e2adf20832abac006bd8bf2c64 100644 --- a/backend/lib-calendar/gradle.lockfile +++ b/backend/lib-calendar/gradle.lockfile @@ -1,21 +1,22 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -53,23 +54,23 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-central-repository-api/gradle.lockfile b/backend/lib-central-repository-api/gradle.lockfile index ccfdfd43f3cb93bebecc6135018c6cc86add9f06..f273afa2edfa6cab232931c2de6e0c1676b0658d 100644 --- a/backend/lib-central-repository-api/gradle.lockfile +++ b/backend/lib-central-repository-api/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -11,9 +11,9 @@ com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2=compileClasspath,p com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -55,24 +55,24 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-central-repository-client/build.gradle b/backend/lib-central-repository-client/build.gradle index d244ff30dcb4fabbbc8b0bf050980d849dc7ae72..5883a963019e0b90ae78417ebaedc9e873804b1b 100644 --- a/backend/lib-central-repository-client/build.gradle +++ b/backend/lib-central-repository-client/build.gradle @@ -6,7 +6,7 @@ dependencies { api project(':lib-central-repository-api') implementation project(':rest-client-commons') - implementation project(':test-helper-commons') + implementation project(':test-helper-commons-spring') implementation 'org.springframework.boot:spring-boot' implementation 'org.springframework.boot:spring-boot-autoconfigure' diff --git a/backend/lib-central-repository-client/gradle.lockfile b/backend/lib-central-repository-client/gradle.lockfile index c46fcc19e395d140f2d6d19648adc4d1c3453985..69ccceab6cf19ef68c884018227950c1e1eb04c7 100644 --- a/backend/lib-central-repository-client/gradle.lockfile +++ b/backend/lib-central-repository-client/gradle.lockfile @@ -1,73 +1,47 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.fasterxml:classmate:1.7.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.github.curious-odd-man:rgxgen:2.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.github.stephenc.jcip:jcip-annotations:1.0-1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.nimbusds:nimbus-jose-jwt:9.37.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.sun.istack:istack-commons-runtime:4.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.annotation:jakarta.annotation-api:2.1.1=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -jakarta.persistence:jakarta.persistence-api:3.1.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -jakarta.transaction:jakarta.transaction-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath net.bytebuddy:byte-buddy-agent:1.14.19=testCompileClasspath,testRuntimeClasspath -net.bytebuddy:byte-buddy:1.14.19=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -net.datafaker:datafaker:2.3.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +net.bytebuddy:byte-buddy:1.14.19=testCompileClasspath,testRuntimeClasspath net.minidev:accessors-smart:2.5.1=testCompileClasspath,testRuntimeClasspath net.minidev:json-smart:2.5.1=testCompileClasspath,testRuntimeClasspath -org.antlr:antlr4-runtime:4.13.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.commons:commons-lang3:3.14.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.httpcomponents.client5:httpclient5:5.3.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath -org.checkerframework:checker-qual:3.43.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.eclipse.angus:angus-activation:2.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.glassfish.jaxb:jaxb-core:4.0.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.glassfish.jaxb:jaxb-runtime:4.0.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.glassfish.jaxb:txw2:4.0.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath -org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt org.jacoco:org.jacoco.report:0.8.11=jacocoAnt -org.jboss.logging:jboss-logging:3.5.3.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.junit.jupiter:junit-jupiter-api:5.10.3=testCompileClasspath,testRuntimeClasspath org.junit.jupiter:junit-jupiter-engine:5.10.3=testRuntimeClasspath org.junit.jupiter:junit-jupiter-params:5.10.3=testCompileClasspath,testRuntimeClasspath @@ -78,7 +52,7 @@ org.junit.platform:junit-platform-launcher:1.10.3=testRuntimeClasspath org.junit:junit-bom:5.10.3=testCompileClasspath,testRuntimeClasspath org.mockito:mockito-core:5.11.0=testCompileClasspath,testRuntimeClasspath org.mockito:mockito-junit-jupiter:5.11.0=testCompileClasspath,testRuntimeClasspath -org.objenesis:objenesis:3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.objenesis:objenesis:3.3=testRuntimeClasspath org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt @@ -87,32 +61,30 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-core:6.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-jose:6.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-resource-server:6.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath -org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.yaml:snakeyaml:2.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.zalando:faux-pas:0.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.zalando:logbook-api:3.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.zalando:logbook-common:3.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath diff --git a/backend/lib-commons/gradle.lockfile b/backend/lib-commons/gradle.lockfile index b7630d8cdd1cd872bfe2c81f1f31ea500a7e24fb..0dccf585508f79ea672a181febfba0ac3e39fbf0 100644 --- a/backend/lib-commons/gradle.lockfile +++ b/backend/lib-commons/gradle.lockfile @@ -1,12 +1,12 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testRuntimeClasspath @@ -42,20 +42,20 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,compileClasspath,developmentOnly,productionRuntimeClasspath,runtimeClasspath,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-document-generator/gradle.lockfile b/backend/lib-document-generator/gradle.lockfile index d27bf1c7b71e520884e9306224384964a2f1d0c0..d6e9c811694ccb4726478f020a0853d47db68a57 100644 --- a/backend/lib-document-generator/gradle.lockfile +++ b/backend/lib-document-generator/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=productionRuntimeClasspath,runtimeClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=productionRuntimeClasspath,runtimeClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -15,8 +15,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=productionRuntimeClasspath,runti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.nimbusds:nimbus-jose-jwt:9.37.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -24,24 +25,23 @@ com.sun.istack:istack-commons-runtime:4.1.2=productionRuntimeClasspath,runtimeCl com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.11.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath commons-logging:commons-logging:1.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=productionRuntimeClasspath,runtimeClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=productionRuntimeClasspath,runtimeClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.rototor.pdfbox:graphics2d:3.0.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-core:1.1.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-pdfbox:1.1.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-slf4j:1.1.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-svg-support:1.1.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -62,8 +62,8 @@ org.apache.pdfbox:fontbox:3.0.3=compileClasspath,productionRuntimeClasspath,runt org.apache.pdfbox:pdfbox-io:3.0.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.pdfbox:pdfbox:3.0.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.pdfbox:xmpbox:3.0.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-anim:1.17=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-awt-util:1.17=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-bridge:1.17=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -94,7 +94,7 @@ org.glassfish.jaxb:jaxb-runtime:4.0.5=productionRuntimeClasspath,runtimeClasspat org.glassfish.jaxb:txw2:4.0.5=productionRuntimeClasspath,runtimeClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt @@ -120,29 +120,29 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-core:6.3.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-jose:6.3.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-resource-server:6.3.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.verapdf:core-jakarta:1.26.1=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.verapdf:feature-reporting-jakarta:1.26.1=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.verapdf:metadata-fixer-jakarta:1.26.1=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath diff --git a/backend/lib-editor-api/gradle.lockfile b/backend/lib-editor-api/gradle.lockfile index 13cdc1dc47e2d36cd5c9e795196911810263c462..f60d03e22d075439c1b6051f93bd529783a3e135 100644 --- a/backend/lib-editor-api/gradle.lockfile +++ b/backend/lib-editor-api/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -11,9 +11,9 @@ com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2=compileClasspath,p com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -54,21 +54,21 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-editor/gradle.lockfile b/backend/lib-editor/gradle.lockfile index 08943e8ba3283ba737dc9b0381923f0419a351bd..fc68545cc5ee0b3f8cab4bb088a1d72475f5cf28 100644 --- a/backend/lib-editor/gradle.lockfile +++ b/backend/lib-editor/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -35,17 +36,17 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -53,14 +54,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -80,10 +80,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -100,7 +100,7 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -125,7 +125,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -133,26 +133,26 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -161,19 +161,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.19.8=testCompileClasspath,testRuntimeClasspath org.webjars:swagger-ui:5.17.14=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath diff --git a/backend/lib-four-eyes-principle-api/gradle.lockfile b/backend/lib-four-eyes-principle-api/gradle.lockfile index 13cdc1dc47e2d36cd5c9e795196911810263c462..f60d03e22d075439c1b6051f93bd529783a3e135 100644 --- a/backend/lib-four-eyes-principle-api/gradle.lockfile +++ b/backend/lib-four-eyes-principle-api/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -11,9 +11,9 @@ com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2=compileClasspath,p com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -54,21 +54,21 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-four-eyes-principle/gradle.lockfile b/backend/lib-four-eyes-principle/gradle.lockfile index d77457b1b3047cb76172020e8d9331008670c9ae..9510eb41c0ce521e0749ec02d934fa0cb8b39111 100644 --- a/backend/lib-four-eyes-principle/gradle.lockfile +++ b/backend/lib-four-eyes-principle/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.h2database:h2:2.2.224=testRuntimeClasspath @@ -41,8 +42,8 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -50,11 +51,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -62,14 +63,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -92,10 +92,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -112,9 +112,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -140,7 +140,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -148,30 +148,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -181,19 +181,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath diff --git a/backend/lib-keycloak/gradle.lockfile b/backend/lib-keycloak/gradle.lockfile index 550e083f4faac4a84b334a817fd211e19127c127..296abc4765e1eff2f5cefd41108e28fc0fed089b 100644 --- a/backend/lib-keycloak/gradle.lockfile +++ b/backend/lib-keycloak/gradle.lockfile @@ -1,18 +1,19 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testRuntimeClasspath @@ -49,21 +50,21 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-keycloak/src/main/java/de/eshg/lib/keycloak/EmployeePermissionRole.java b/backend/lib-keycloak/src/main/java/de/eshg/lib/keycloak/EmployeePermissionRole.java index c6013455af04b6528b3d406def8316d1b512f988..21b27db6f9e8f0f51285057061b1c6379f402b50 100644 --- a/backend/lib-keycloak/src/main/java/de/eshg/lib/keycloak/EmployeePermissionRole.java +++ b/backend/lib-keycloak/src/main/java/de/eshg/lib/keycloak/EmployeePermissionRole.java @@ -256,8 +256,8 @@ public enum EmployeePermissionRole implements PermissionRole { STI_PROTECTION_USER( "HIV-STI Benutzer", Module.STI_PROTECTION, - BASE_PERSONS_READ // required to access progress entries - ), + BASE_PERSONS_READ, // required to access progress entries + BASE_CALENDAR_BUSINESS_EVENTS_WRITE), STI_PROTECTION_MFA("HIV-STI MFA", Module.STI_PROTECTION, STI_PROTECTION_USER), STI_PROTECTION_CONSULTANT("HIV-STI Berater", Module.STI_PROTECTION, STI_PROTECTION_USER), STI_PROTECTION_PHYSICIAN("HIV-STI Arzt", Module.STI_PROTECTION, STI_PROTECTION_USER), diff --git a/backend/lib-lsd-api/gradle.lockfile b/backend/lib-lsd-api/gradle.lockfile index 66df3acb5aaa14dcda3fc7a9f6f514f686cdce84..0255191c5a2221cc7c683c1cd09e64cf6281879e 100644 --- a/backend/lib-lsd-api/gradle.lockfile +++ b/backend/lib-lsd-api/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath @@ -24,8 +24,9 @@ com.github.java-json-tools:msg-simple:1.2=compileClasspath,productionRuntimeClas com.google.code.findbugs:jsr305:3.0.2=testFixturesRuntimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.ibm.async:asyncutil:0.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath @@ -45,17 +46,17 @@ com.tngtech.archunit:archunit:1.3.0=testFixturesRuntimeClasspath,testRuntimeClas com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath commons-codec:commons-codec:1.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath commons-io:commons-io:2.11.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testFixturesRuntimeClasspath +commons-io:commons-io:2.17.0=testFixturesRuntimeClasspath commons-logging:commons-logging:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.quarkus:quarkus-junit4-mock:3.14.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.quarkus:quarkus-junit4-mock:3.15.0=testCompileClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=testFixturesRuntimeClasspath,testRuntimeClasspath @@ -102,7 +103,7 @@ org.glassfish.jaxb:xsom:4.0.5=compileClasspath,productionRuntimeClasspath,runtim org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=testFixturesRuntimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=testFixturesRuntimeClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt @@ -129,9 +130,9 @@ org.junit.platform:junit-platform-commons:1.10.3=testCompileClasspath,testFixtur org.junit.platform:junit-platform-engine:1.10.3=testFixturesRuntimeClasspath,testRuntimeClasspath org.junit.platform:junit-platform-launcher:1.10.3=testRuntimeClasspath org.junit:junit-bom:5.10.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.keycloak:keycloak-admin-client:25.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.keycloak:keycloak-common:25.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.keycloak:keycloak-core:25.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.keycloak:keycloak-admin-client:25.0.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.keycloak:keycloak-common:25.0.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.keycloak:keycloak-core:25.0.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.mockito:mockito-core:5.11.0=testCompileClasspath,testRuntimeClasspath org.mockito:mockito-junit-jupiter:5.11.0=testCompileClasspath,testRuntimeClasspath org.objenesis:objenesis:3.3=testRuntimeClasspath @@ -139,32 +140,32 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testFixturesCompileClasspat org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testFixturesRuntimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testFixturesRuntimeClasspath,testRuntimeClasspath org.reactivestreams:reactive-streams:1.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath diff --git a/backend/lib-mutex/gradle.lockfile b/backend/lib-mutex/gradle.lockfile index ba4c6d004a6cd67efca2299b4f356928b7b15306..73d4aa01932eb87b36cf814c849b69f65fe89aa2 100644 --- a/backend/lib-mutex/gradle.lockfile +++ b/backend/lib-mutex/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -37,8 +38,8 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -46,11 +47,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -58,14 +59,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -88,10 +88,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -108,8 +108,8 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -135,7 +135,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -143,29 +143,29 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -174,19 +174,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath diff --git a/backend/lib-notification-api/gradle.lockfile b/backend/lib-notification-api/gradle.lockfile index 5bc346698038a3d492a1ed23468cd1fbb94699db..e551c350f68f8a2df4cb6061a7c81df82b70ecd6 100644 --- a/backend/lib-notification-api/gradle.lockfile +++ b/backend/lib-notification-api/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -11,9 +11,9 @@ com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2=productionRuntimeC com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -54,21 +54,21 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-notification/gradle.lockfile b/backend/lib-notification/gradle.lockfile index 53e87ceb63283376245882f26eae0e23832b383d..5bd8b9f45c6d4f166ac99b0c92da87efdd94cd81 100644 --- a/backend/lib-notification/gradle.lockfile +++ b/backend/lib-notification/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.h2database:h2:2.2.224=testRuntimeClasspath @@ -38,8 +39,8 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -47,11 +48,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -59,14 +60,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -89,10 +89,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -109,9 +109,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -137,7 +137,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -145,29 +145,29 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -176,19 +176,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath diff --git a/backend/lib-procedures-api/gradle.lockfile b/backend/lib-procedures-api/gradle.lockfile index adadb437a7503504646411c2fc364f71d949ffa5..dbff45dc1ed5052cab228b3706e75108689cef80 100644 --- a/backend/lib-procedures-api/gradle.lockfile +++ b/backend/lib-procedures-api/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -12,9 +12,9 @@ com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClass com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -56,21 +56,21 @@ org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/ProcedureMetricsApi.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/ProcedureMetricsApi.java index a19254c2d743fa153afba62a3fb484de15c7e540..22ad13241063f295599c8f297a53a4fd5cb338d4 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/ProcedureMetricsApi.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/ProcedureMetricsApi.java @@ -8,7 +8,6 @@ package de.eshg.lib.procedure.api; import static de.eshg.lib.procedure.api.ProcedureMetricsApi.QueryParameter.TIME_RANGE_END; import static de.eshg.lib.procedure.api.ProcedureMetricsApi.QueryParameter.TIME_RANGE_START; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.procedure.model.GetProcedureMetricsResponse; import de.eshg.rest.service.security.config.BaseUrls.ProcedureLibrary; import io.swagger.v3.oas.annotations.Operation; @@ -33,6 +32,6 @@ public interface ProcedureMetricsApi { @ApiResponse(responseCode = "200", description = "the metrics of procedures") @Operation(summary = "Get procedure metrics for procedures created in the given time range") GetProcedureMetricsResponse getProcedureMetrics( - @CanBeLogged @RequestParam(name = TIME_RANGE_START) Instant timeRangeStart, - @CanBeLogged @RequestParam(name = TIME_RANGE_END) Instant timeRangeEnd); + @RequestParam(name = TIME_RANGE_START) Instant timeRangeStart, + @RequestParam(name = TIME_RANGE_END) Instant timeRangeEnd); } diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/RecentProcedureApi.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/RecentProcedureApi.java index a59895644c402754c579aa2996ae8e6dfa6317c3..28d44051a7995502eaf829e6be2d41accc06610d 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/RecentProcedureApi.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/RecentProcedureApi.java @@ -7,7 +7,6 @@ package de.eshg.lib.procedure.api; import static de.eshg.lib.procedure.api.RecentProcedureApi.QueryParameter.*; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.procedure.model.GetRecentProceduresResponse; import de.eshg.lib.procedure.model.ProcedureStatusDto; import de.eshg.lib.procedure.model.ProcedureTypeDto; @@ -39,14 +38,10 @@ public interface RecentProcedureApi { @ApiResponse(responseCode = "200", description = "the current users recent procedures") @Operation(summary = "Get recent procedures for the current user") GetRecentProceduresResponse getSelfRecentProcedures( - @CanBeLogged @RequestParam(name = PROCEDURE_TYPE, required = false) - Set<ProcedureTypeDto> procedureTypes, - @CanBeLogged @RequestParam(name = PROCEDURE_STATUS, required = false) + @RequestParam(name = PROCEDURE_TYPE, required = false) Set<ProcedureTypeDto> procedureTypes, + @RequestParam(name = PROCEDURE_STATUS, required = false) Set<ProcedureStatusDto> procedureStatus, - @CanBeLogged - @RequestParam(name = LIMIT, required = false, defaultValue = "50") - @Min(1) - @Max(200) + @RequestParam(name = LIMIT, required = false, defaultValue = "50") @Min(1) @Max(200) Integer limit); @GetExchange(RECENT_PROCEDURES_API_PATH) @@ -54,13 +49,9 @@ public interface RecentProcedureApi { @Operation(summary = "Get recent procedures for user") GetRecentProceduresResponse getRecentProcedures( @RequestParam(name = USER_ID) UUID userId, - @CanBeLogged @RequestParam(name = PROCEDURE_TYPE, required = false) - Set<ProcedureTypeDto> procedureTypes, - @CanBeLogged @RequestParam(name = PROCEDURE_STATUS, required = false) + @RequestParam(name = PROCEDURE_TYPE, required = false) Set<ProcedureTypeDto> procedureTypes, + @RequestParam(name = PROCEDURE_STATUS, required = false) Set<ProcedureStatusDto> procedureStatus, - @CanBeLogged - @RequestParam(name = LIMIT, required = false, defaultValue = "50") - @Min(1) - @Max(200) + @RequestParam(name = LIMIT, required = false, defaultValue = "50") @Min(1) @Max(200) Integer limit); } diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/TaskListApi.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/TaskListApi.java index fa00f0dedb640e8d01be76258ab3585058924e04..435f1c4b0f612298e329a6c876ab7a3b1618a21b 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/TaskListApi.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/TaskListApi.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.api; -import de.eshg.api.commons.CanBeLogged; import de.eshg.api.commons.InlineParameterObject; import de.eshg.lib.procedure.model.GetTasksFilterOptions; import de.eshg.lib.procedure.model.GetTasksSortByDto; @@ -52,8 +51,7 @@ public interface TaskListApi { TaskResponse getTasks( @InlineParameterObject @ParameterObject @Valid GetTasksFilterOptions filterOptions, @InlineParameterObject @ParameterObject @Valid GetTasksSortOptions sortOptions, - @CanBeLogged - @RequestParam(name = QueryParameter.LIMIT, required = false, defaultValue = "50") + @RequestParam(name = QueryParameter.LIMIT, required = false, defaultValue = "50") @Min(1) @Max(200) Integer limit); diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/TaskMetricsApi.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/TaskMetricsApi.java index 3e283cdaa9e89bb483cd42fc5139e18143bf65f6..79c5ca13604e0010b259a5d72240b897a6c297df 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/TaskMetricsApi.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/api/TaskMetricsApi.java @@ -9,7 +9,6 @@ import static de.eshg.lib.procedure.api.ProcedureApi.QueryParameter.PROCEDURE_TY import static de.eshg.lib.procedure.api.ProcedureMetricsApi.QueryParameter.TIME_RANGE_END; import static de.eshg.lib.procedure.api.ProcedureMetricsApi.QueryParameter.TIME_RANGE_START; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.procedure.model.GetTaskMetricsResponse; import de.eshg.lib.procedure.model.ProcedureTypeDto; import de.eshg.rest.service.security.config.BaseUrls; @@ -27,7 +26,7 @@ public interface TaskMetricsApi { summary = "Get tasks metrics for a procedure type of a business module for procedures created in the given time range") GetTaskMetricsResponse getTaskMetrics( - @CanBeLogged @RequestParam(name = PROCEDURE_TYPE) ProcedureTypeDto procedureType, - @CanBeLogged @RequestParam(name = TIME_RANGE_START) Instant timeRangeStart, - @CanBeLogged @RequestParam(name = TIME_RANGE_END) Instant timeRangeEnd); + @RequestParam(name = PROCEDURE_TYPE) ProcedureTypeDto procedureType, + @RequestParam(name = TIME_RANGE_START) Instant timeRangeStart, + @RequestParam(name = TIME_RANGE_END) Instant timeRangeEnd); } diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractFileDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractFileDto.java index 770c48dbdfb1e4fa5dc1af78d8c0a143b45a063a..89d65dd1983c08d73aa09ef3f09926356431246f 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractFileDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractFileDto.java @@ -6,7 +6,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import java.time.Instant; @@ -18,14 +17,14 @@ public abstract sealed class AbstractFileDto extends AbstractFileReferenceDto permits GenericFileDto, ConcreteFileDto { public static final String SCHEMA_NAME = "AbstractFile"; - private @CanBeLogged @NotNull Instant createdAt; - private @CanBeLogged @NotNull Instant modifiedAt; + private @NotNull Instant createdAt; + private @NotNull Instant modifiedAt; private @NotNull UUID createdBy; private @NotNull String fileName; - private @CanBeLogged @NotNull FileTypeDto fileType; - private @CanBeLogged @NotNull int fileSizeBytes; + private @NotNull FileTypeDto fileType; + private @NotNull int fileSizeBytes; private UUID attachedToMail; - private @CanBeLogged @NotNull boolean locked; + private @NotNull boolean locked; public Instant getCreatedAt() { return createdAt; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractFileReferenceDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractFileReferenceDto.java index 1eae12e38c83d78b98109bbb6ac0bcba2aa5627a..4f0062647d81d439ed543d5825cba32b66ec9327 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractFileReferenceDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractFileReferenceDto.java @@ -6,7 +6,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import java.util.UUID; @@ -19,8 +18,8 @@ public abstract sealed class AbstractFileReferenceDto public static final String SCHEMA_NAME = "AbstractFileReference"; @NotNull private UUID fileId; - @CanBeLogged @NotNull private boolean deleted; - @CanBeLogged @NotNull private boolean deletable; + @NotNull private boolean deleted; + @NotNull private boolean deletable; public void setFileId(UUID fileId) { this.fileId = fileId; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractHistoryDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractHistoryDto.java index 8ff169e62c387dfe54d83aea42fdd12807163765..5fe6fc5213ffd00deaf4f5372f04dfd9965b6d84 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractHistoryDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AbstractHistoryDto.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import jakarta.validation.constraints.NotNull; import java.time.Instant; import java.util.UUID; @@ -13,7 +12,7 @@ import java.util.UUID; public class AbstractHistoryDto { @NotNull private UUID changedBy; - @CanBeLogged @NotNull private Instant changedAt; + @NotNull private Instant changedAt; public void setChangedAt(Instant changedAt) { this.changedAt = changedAt; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ArchivingRelevanceSettingsDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ArchivingRelevanceSettingsDto.java index e0908af0567169ac7b0de3706ac1325ee25d6fc1..f81d0bc60bae4b78ffc28e6e34bc86140f384d46 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ArchivingRelevanceSettingsDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ArchivingRelevanceSettingsDto.java @@ -5,11 +5,10 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; @Schema(name = "ArchivingRelevanceSettings") public record ArchivingRelevanceSettingsDto( - @CanBeLogged @NotNull ArchivingRelevanceDto archivingRelevance, - @CanBeLogged @NotNull ArchivingRelevanceDto defaultArchivingRelevance) {} + @NotNull ArchivingRelevanceDto archivingRelevance, + @NotNull ArchivingRelevanceDto defaultArchivingRelevance) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AssignTaskRequest.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AssignTaskRequest.java index 251edb6fc3bb9e576964ba2ec1e679fcef4a8fe9..b45c37a8c631ef385a016ff0338b9bc36e032ce6 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AssignTaskRequest.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/AssignTaskRequest.java @@ -5,10 +5,10 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import jakarta.validation.constraints.Future; import jakarta.validation.constraints.NotNull; import java.time.Instant; import java.util.UUID; -public record AssignTaskRequest(@NotNull UUID assignee, @CanBeLogged @Future Instant dueAt) {} +public record AssignTaskRequest( + @NotNull Long taskVersion, @NotNull UUID assignee, @Future Instant dueAt) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ContactDetailsDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ContactDetailsDto.java index dfb492c53a408d999363a5d4e43d2f383f87197e..43880496be3cd4d1cadf022d77d36fece1ad81ed 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ContactDetailsDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ContactDetailsDto.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -13,7 +12,7 @@ import java.time.LocalDate; @Schema(name = "ContactDetails") public record ContactDetailsDto( - @CanBeLogged @NotNull ContactTypeDto contactType, + @NotNull ContactTypeDto contactType, String facilityName, String firstName, String lastName, diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateInboxProcedureRequest.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateInboxProcedureRequest.java index 7d3d4fa8ae1a993503613f249f9811dd1cd5203f..b220969d5f54f2cc98e47cd639b380021e004cef 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateInboxProcedureRequest.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateInboxProcedureRequest.java @@ -5,11 +5,10 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; public record CreateInboxProcedureRequest( - @CanBeLogged ProcedureTypeDto inboxProcedureType, + ProcedureTypeDto inboxProcedureType, @Valid @NotNull CreateInboxProgressEntryDto inboxProgressEntry, @Valid @NotNull ContactDetailsDto contactDetails) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateInboxProgressEntryDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateInboxProgressEntryDto.java index ccc8188c74fcd04c0c857e19fb8e826cce709c3e..b9da3973c078aeb6f6a9ac6624b31e22a366b508 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateInboxProgressEntryDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateInboxProgressEntryDto.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; @@ -13,4 +12,4 @@ import jakarta.validation.constraints.NotNull; public record CreateInboxProgressEntryDto( String subject, String messageText, - @CanBeLogged @NotNull InboxProgressEntryTypeDto inboxProgressEntryType) {} + @NotNull InboxProgressEntryTypeDto inboxProgressEntryType) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateManualProgressEntryRequest.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateManualProgressEntryRequest.java index b919188ee0821d0fdda1fcfde4306a564ccf7194..1586c21f6e60a94c4acc83944c2d1a4dbfd55d12 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateManualProgressEntryRequest.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/CreateManualProgressEntryRequest.java @@ -5,12 +5,11 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import jakarta.validation.constraints.NotNull; public record CreateManualProgressEntryRequest( - @CanBeLogged @NotNull ManualProgressEntryTypeDto manualProgressEntryType, + @NotNull ManualProgressEntryTypeDto manualProgressEntryType, String subject, String messageText, String note, - @CanBeLogged KeyDocumentTypeDto keyDocumentType) {} + KeyDocumentTypeDto keyDocumentType) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedFacilityDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedFacilityDto.java index 0403173cd26c5edd7effd8039990eeacb0c37030..baa02800b973af65195dee48cb23773199e7fb2d 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedFacilityDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedFacilityDto.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import de.eshg.base.centralfile.api.facility.AddFacilityFileStateResponse; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; @@ -14,4 +13,4 @@ import jakarta.validation.constraints.NotNull; @Schema(name = "DetailedFacility") public record DetailedFacilityDto( @NotNull @Valid AddFacilityFileStateResponse facilityFileState, - @CanBeLogged @NotNull FacilityTypeDto facilityType) {} + @NotNull FacilityTypeDto facilityType) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedPersonDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedPersonDto.java index 8346c63a29e29b58ecce0e8eb99a6080bb4d6372..2c5a3117cfaf1bb7b3a89fa33864651bf137fd5b 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedPersonDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedPersonDto.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import de.eshg.base.centralfile.api.person.AddPersonFileStateResponse; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; @@ -13,5 +12,4 @@ import jakarta.validation.constraints.NotNull; @Schema(name = "DetailedPerson") public record DetailedPersonDto( - @Valid @NotNull AddPersonFileStateResponse person, - @CanBeLogged @NotNull PersonTypeDto personType) {} + @Valid @NotNull AddPersonFileStateResponse person, @NotNull PersonTypeDto personType) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedTaskDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedTaskDto.java index e81246de9b9bf53bef77f5d0c2db19f7df46cd09..d11710f994c269b071158ef82da3fea5d9222181 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedTaskDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/DetailedTaskDto.java @@ -5,11 +5,10 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @Schema(name = "DetailedTask") public record DetailedTaskDto( - @CanBeLogged @NotNull @Valid TaskDto task, String assigneeName, String assignedByName) {} + @NotNull @Valid TaskDto task, String assigneeName, String assignedByName) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresFilterOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresFilterOptions.java index 6782fc312b4b084ed36516401aca5ff9c16d3872..8f6794d12a1079e2e4f15150582c793a69b37f51 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresFilterOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresFilterOptions.java @@ -9,7 +9,6 @@ import static de.eshg.lib.procedure.api.ArchivingApi.QueryParameter.CLOSED_AT_DA import static de.eshg.lib.procedure.api.ArchivingApi.QueryParameter.DEFAULT_ARCHIVING_RELEVANCE; import static de.eshg.lib.procedure.api.ArchivingApi.QueryParameter.PROCEDURE_TYPE; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import java.time.LocalDate; import java.util.Set; @@ -18,8 +17,7 @@ import org.springframework.web.bind.annotation.BindParam; @ParameterObject public record GetArchivableProceduresFilterOptions( - @CanBeLogged - @BindParam(PROCEDURE_TYPE) + @BindParam(PROCEDURE_TYPE) @Parameter( description = """ @@ -28,8 +26,7 @@ public record GetArchivableProceduresFilterOptions( - If not submitted, no filtering takes place """) Set<ProcedureTypeDto> procedureType, - @CanBeLogged - @Parameter( + @Parameter( description = """ Filter logic: @@ -38,8 +35,7 @@ public record GetArchivableProceduresFilterOptions( """) @BindParam(CLOSED_AT_DAY) LocalDate closedAtDay, - @CanBeLogged - @BindParam(DEFAULT_ARCHIVING_RELEVANCE) + @BindParam(DEFAULT_ARCHIVING_RELEVANCE) @Parameter( description = """ diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresResponse.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresResponse.java index c1df217bfca40bd92ca2f4225229f9388db9ec31..5508c4cebd21eefc0a76661374b079741bc6d78a 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresResponse.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresResponse.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -13,12 +12,8 @@ import jakarta.validation.constraints.Size; import java.util.List; public record GetArchivableProceduresResponse( - @CanBeLogged - @NotNull - @Schema(description = "Total number of result pages for the given filter criteria") + @NotNull @Schema(description = "Total number of result pages for the given filter criteria") int totalPages, - @CanBeLogged - @NotNull - @Schema(description = "Total number of result elements for the given filter criteria") + @NotNull @Schema(description = "Total number of result elements for the given filter criteria") long totalElements, @Valid @NotNull @Size(max = 200) List<ProcedureDto> procedures) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresSortOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresSortOptions.java index 6cbcda524f4590ea2c58a3b1ef1fdf4cee97ebcc..adce540d9e485c266b06b277b5046f06893197c7 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresSortOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivableProceduresSortOptions.java @@ -8,15 +8,13 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.api.ArchivingApi.QueryParameter.SORT_BY; import static de.eshg.lib.procedure.api.ArchivingApi.QueryParameter.SORT_ORDER; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema; import java.util.Objects; import org.springframework.web.bind.annotation.BindParam; public record GetArchivableProceduresSortOptions( - @CanBeLogged - @Parameter( + @Parameter( description = """ The following sorting options are available: @@ -24,12 +22,9 @@ public record GetArchivableProceduresSortOptions( - `PROCEDURE_TYPE`: Sorting by procedureType attribute """) @BindParam(SORT_BY) - @Schema(defaultValue = "CREATED_AT") + @Schema(defaultValue = "CLOSED_AT") GetArchivableProceduresSortByDto sortBy, - @CanBeLogged - @Parameter(description = "Sorting order.") - @BindParam(SORT_ORDER) - @Schema(defaultValue = "ASC") + @Parameter(description = "Sorting order.") @BindParam(SORT_ORDER) @Schema(defaultValue = "ASC") GetArchivableProceduresSortOrderDto sortOrder) { public GetArchivableProceduresSortOptions( diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivingConfigurationResponse.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivingConfigurationResponse.java index 5a329c19cad970bbb59bd04b7a765ed59a645ad7..0c60c44c417373d7da3aad76d5a7337cc82aeb6b 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivingConfigurationResponse.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivingConfigurationResponse.java @@ -5,12 +5,11 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import java.util.Map; public record GetArchivingConfigurationResponse( - @CanBeLogged @NotNull int gracePeriodMonths, - @CanBeLogged @NotEmpty @Valid Map<ProcedureTypeDto, ArchivingDetailsDto> archivingDetails) {} + @NotNull int gracePeriodMonths, + @NotEmpty @Valid Map<ProcedureTypeDto, ArchivingDetailsDto> archivingDetails) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivingEndpointsResponse.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivingEndpointsResponse.java index 088bd70c7c0794ee3352c892453ebd910736ece2..606ebb58fe5ce89a2cc9c7f57e10c429ffdd67ec 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivingEndpointsResponse.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetArchivingEndpointsResponse.java @@ -5,11 +5,9 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import java.util.Map; public record GetArchivingEndpointsResponse( - @CanBeLogged @Valid @NotNull Map<String, String> endpoints, - @CanBeLogged String defaultEndpointId) {} + @Valid @NotNull Map<String, String> endpoints, String defaultEndpointId) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresFilterOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresFilterOptions.java index 4c2181dfab7441e8958eb69d59f18bf695343a4a..67b0476880217d517b7878f9479a5a04f94df591 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresFilterOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresFilterOptions.java @@ -9,7 +9,6 @@ import static de.eshg.lib.procedure.api.InboxProcedureApi.QueryParameter.INBOX_P import static de.eshg.lib.procedure.api.InboxProcedureApi.QueryParameter.INBOX_PROCEDURE_TYPE; import static de.eshg.lib.procedure.api.InboxProcedureApi.QueryParameter.INCLUDE_UNTYPED; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import java.util.Set; import org.springdoc.core.annotations.ParameterObject; @@ -17,8 +16,7 @@ import org.springframework.web.bind.annotation.BindParam; @ParameterObject public record GetInboxProceduresFilterOptions( - @CanBeLogged - @BindParam(INBOX_PROCEDURE_TYPE) + @BindParam(INBOX_PROCEDURE_TYPE) @Parameter( description = """ @@ -27,8 +25,7 @@ public record GetInboxProceduresFilterOptions( - If not submitted, no filtering takes place. """) Set<ProcedureTypeDto> inboxProcedureType, - @CanBeLogged - @Parameter( + @Parameter( description = """ Filter logic: @@ -37,8 +34,7 @@ public record GetInboxProceduresFilterOptions( """) @BindParam(INCLUDE_UNTYPED) Boolean includeUntyped, - @CanBeLogged - @BindParam(INBOX_PROCEDURE_STATUS) + @BindParam(INBOX_PROCEDURE_STATUS) @Parameter( description = """ diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresPaginationOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresPaginationOptions.java index 9d3a60f27c72d33b22965b7dea2b88555b6e9e17..c4529bcd25d8f92f745c08740bf1e2955baf3ae4 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresPaginationOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresPaginationOptions.java @@ -7,7 +7,6 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.api.InboxProcedureApi.QueryParameter.*; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Max; @@ -17,14 +16,12 @@ import java.util.Objects; import org.springframework.web.bind.annotation.BindParam; public record GetInboxProceduresPaginationOptions( - @CanBeLogged - @Parameter(description = "Number of the requested page") + @Parameter(description = "Number of the requested page") @BindParam(value = PAGE_NUMBER) @Schema(defaultValue = "0") @PositiveOrZero Integer pageNumber, - @CanBeLogged - @Parameter(description = "Amount of requested inbox procedures") + @Parameter(description = "Amount of requested inbox procedures") @BindParam(value = PAGE_SIZE) @Schema(defaultValue = DEFAULT_PAGE_SIZE) @Min(1) diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresResponse.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresResponse.java index 137a3310b2d7cab636361c819c2481c2d2c2de8d..526203c1455c51d64004b001d28b818a77d056cc 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresResponse.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresResponse.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -13,12 +12,8 @@ import jakarta.validation.constraints.Size; import java.util.List; public record GetInboxProceduresResponse( - @CanBeLogged - @NotNull - @Schema(description = "Total number of result pages for the given filter criteria") + @NotNull @Schema(description = "Total number of result pages for the given filter criteria") int totalPages, - @CanBeLogged - @NotNull - @Schema(description = "Total number of result elements for the given filter criteria") + @NotNull @Schema(description = "Total number of result elements for the given filter criteria") long totalElements, @Valid @NotNull @Size(max = 200) List<InboxProcedureDto> inboxProcedures) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresSortOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresSortOptions.java index 69fc22def73264af8b5c6f2e64447f8b68e7825d..924d05e22150f57ee694e499e41fa92028c8bb7e 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresSortOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetInboxProceduresSortOptions.java @@ -8,15 +8,13 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.api.InboxProcedureApi.QueryParameter.SORT_BY; import static de.eshg.lib.procedure.api.InboxProcedureApi.QueryParameter.SORT_ORDER; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema; import java.util.Objects; import org.springframework.web.bind.annotation.BindParam; public record GetInboxProceduresSortOptions( - @CanBeLogged - @Parameter( + @Parameter( description = """ The following sorting options are available: @@ -26,10 +24,7 @@ public record GetInboxProceduresSortOptions( @BindParam(SORT_BY) @Schema(defaultValue = "CREATED_AT") GetInboxProceduresSortByDto sortBy, - @CanBeLogged - @Parameter(description = "Sorting order.") - @BindParam(SORT_ORDER) - @Schema(defaultValue = "ASC") + @Parameter(description = "Sorting order.") @BindParam(SORT_ORDER) @Schema(defaultValue = "ASC") GetInboxProceduresSortOrderDto sortOrder) { public GetInboxProceduresSortOptions( diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresFilterOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresFilterOptions.java index 479bff6075b66fefb5f802c2179af80938e980e6..ef7dd24b7be5b4b40f2729f5139820785ccb75f5 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresFilterOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresFilterOptions.java @@ -13,7 +13,6 @@ import static de.eshg.lib.procedure.api.ProcedureApi.QueryParameter.PROCEDURE_ST import static de.eshg.lib.procedure.api.ProcedureApi.QueryParameter.PROCEDURE_TYPE; import static de.eshg.lib.procedure.api.ProcedureApi.QueryParameter.UNASSIGNED; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import java.time.Year; import java.util.Set; @@ -47,8 +46,7 @@ public record GetProceduresFilterOptions( """) @BindParam(ONCE_ASSIGNED_TO_ID) UUID onceAssignedToId, - @CanBeLogged - @Parameter( + @Parameter( description = """ Filter logic: @@ -58,8 +56,7 @@ public record GetProceduresFilterOptions( """) @BindParam(UNASSIGNED) Boolean unassigned, - @CanBeLogged - @BindParam(PROCEDURE_TYPE) + @BindParam(PROCEDURE_TYPE) @Parameter( description = """ @@ -68,8 +65,7 @@ public record GetProceduresFilterOptions( - If not submitted, no filtering takes place """) Set<ProcedureTypeDto> procedureType, - @CanBeLogged - @BindParam(PROCEDURE_STATUS) + @BindParam(PROCEDURE_STATUS) @Parameter( description = """ @@ -78,8 +74,7 @@ public record GetProceduresFilterOptions( - If not submitted, no filtering takes place """) Set<ProcedureStatusDto> procedureStatus, - @CanBeLogged - @Parameter( + @Parameter( description = """ Filter logic: diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresPaginationOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresPaginationOptions.java index 0623a5c5bf40b02a1c3c55a3182f0e5a9fa3ac23..26e51944aff8a6ec665b5d4141b3c61dad1ffbb3 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresPaginationOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresPaginationOptions.java @@ -8,7 +8,6 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.api.ProcedureApi.QueryParameter.PAGE_NUMBER; import static de.eshg.lib.procedure.api.ProcedureApi.QueryParameter.PAGE_SIZE; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Max; @@ -17,15 +16,13 @@ import java.util.Objects; import org.springframework.web.bind.annotation.BindParam; public record GetProceduresPaginationOptions( - @CanBeLogged - @Parameter(description = "Limit of returned procedures") + @Parameter(description = "Limit of returned procedures") @BindParam(value = PAGE_SIZE) @Schema(defaultValue = "50") @Min(1) @Max(200) Integer pageSize, - @CanBeLogged - @Parameter(description = "Offset used for pagination") + @Parameter(description = "Offset used for pagination") @BindParam(value = PAGE_NUMBER) @Schema(defaultValue = "0") @Min(0) diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresResponse.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresResponse.java index 612241fc6cc4d5de62f768268157b7e84ba538bf..6292ecd2df2633483677b849d7c0893af7d7a6c3 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresResponse.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresResponse.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -13,12 +12,8 @@ import jakarta.validation.constraints.Size; import java.util.List; public record GetProceduresResponse( - @CanBeLogged - @NotNull - @Schema(description = "Total number of result pages for the given filter criteria") + @NotNull @Schema(description = "Total number of result pages for the given filter criteria") int totalPages, - @CanBeLogged - @NotNull - @Schema(description = "Total number of result elements for the given filter criteria") + @NotNull @Schema(description = "Total number of result elements for the given filter criteria") long totalElements, @Valid @NotNull @Size(max = 200) List<ProcedureDto> procedures) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresSortOptionsDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresSortOptionsDto.java index 58bba566350954dc8d5367a58596b3d12cf588db..afcb50400effeb14bdec5e134277aab10dbd9cf0 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresSortOptionsDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProceduresSortOptionsDto.java @@ -8,7 +8,6 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.api.ProcedureApi.QueryParameter.SORT_BY; import static de.eshg.lib.procedure.api.ProcedureApi.QueryParameter.SORT_ORDER; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema; import java.util.Objects; @@ -16,8 +15,7 @@ import org.springframework.web.bind.annotation.BindParam; @Schema(name = "GetProceduresSortOptions") public record GetProceduresSortOptionsDto( - @CanBeLogged - @Parameter( + @Parameter( description = """ The following sorting options are available: @@ -27,10 +25,7 @@ public record GetProceduresSortOptionsDto( @BindParam(SORT_BY) @Schema(defaultValue = "CREATED_AT") GetProceduresSortByDto sortBy, - @CanBeLogged - @Parameter(description = "Sorting order.") - @BindParam(SORT_ORDER) - @Schema(defaultValue = "ASC") + @Parameter(description = "Sorting order.") @BindParam(SORT_ORDER) @Schema(defaultValue = "ASC") GetProceduresSortOrderDto sortOrder) { public GetProceduresSortOptionsDto( diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesFilterOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesFilterOptions.java index 53be7460b0e09f7ef7b550ac2202bc7aaedfd31f..0eec2d04595e17a119413022f7197b814cbc0bba 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesFilterOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesFilterOptions.java @@ -7,19 +7,15 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.api.ProgressEntryApi.QueryParameter.*; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import java.util.Set; import java.util.UUID; import org.springframework.web.bind.annotation.BindParam; public record GetProgressEntriesFilterOptions( - @CanBeLogged - @Parameter(description = "Filter on progressEntryType") - @BindParam(PROGRESS_ENTRY_TYPE) + @Parameter(description = "Filter on progressEntryType") @BindParam(PROGRESS_ENTRY_TYPE) Set<String> progressEntryType, - @CanBeLogged - @Parameter(description = "Filter on child class of progressEntry") + @Parameter(description = "Filter on child class of progressEntry") @BindParam(PROGRESS_ENTRY_CLASS) Set<ProgressEntryClassDto> progressEntryClass, @Parameter( @@ -31,8 +27,7 @@ public record GetProgressEntriesFilterOptions( """) @BindParam(INITIATED_BY) Set<UUID> initiatedBy, - @CanBeLogged - @Parameter( + @Parameter( description = """ Filter on triggerType. diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesResponse.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesResponse.java index af8114da3594176a6090dccf9770ba30baec4b25..b3d1605ba0116fd0f27e6826e91467c2a4a70f76 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesResponse.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesResponse.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -13,12 +12,8 @@ import jakarta.validation.constraints.Size; import java.util.List; public record GetProgressEntriesResponse( - @CanBeLogged - @NotNull - @Schema(description = "Total number of result pages for the given filter criteria") + @NotNull @Schema(description = "Total number of result pages for the given filter criteria") int totalPages, - @CanBeLogged - @NotNull - @Schema(description = "Total number of result elements for the given filter criteria") + @NotNull @Schema(description = "Total number of result elements for the given filter criteria") long totalElements, @Valid @NotNull @Size(max = 200) List<ProgressEntryDto> progressEntries) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesSortOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesSortOptions.java index c53d1468e60b7586c8afb659897586205226009a..383fa191241e1aab0460c7979173378495c6a725 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesSortOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntriesSortOptions.java @@ -8,18 +8,14 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.api.ProgressEntryApi.QueryParameter.SORT_BY; import static de.eshg.lib.procedure.api.ProgressEntryApi.QueryParameter.SORT_ORDER; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import java.util.Objects; import org.springframework.web.bind.annotation.BindParam; public record GetProgressEntriesSortOptions( - @CanBeLogged - @Parameter(description = "Sorting on either modifiedAt or createdAt ") - @BindParam(SORT_BY) + @Parameter(description = "Sorting on either modifiedAt or createdAt ") @BindParam(SORT_BY) ProgressEntrySortByDto sortBy, - @CanBeLogged - @Parameter( + @Parameter( description = "Sorting order. Possible options \"ASC\" for ascending and \"DESC\" for descending.") @BindParam(SORT_ORDER) diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntryPaginationOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntryPaginationOptions.java index 2fc14d87ce5b2296ec905c026646f9185d514a2a..b4d7ac35c78e9ceb3ab30b584b1500f6bf6353ac 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntryPaginationOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetProgressEntryPaginationOptions.java @@ -7,7 +7,6 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.api.ProgressEntryApi.QueryParameter.PAGE_NUMBER; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.procedure.api.ProgressEntryApi.QueryParameter; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema; @@ -18,15 +17,13 @@ import java.util.Objects; import org.springframework.web.bind.annotation.BindParam; public record GetProgressEntryPaginationOptions( - @CanBeLogged - @Parameter(description = "Maximum number of elements to return") + @Parameter(description = "Maximum number of elements to return") @BindParam(value = QueryParameter.PAGE_SIZE) @Schema(defaultValue = "50") @Min(1) @Max(200) Integer pageSize, - @CanBeLogged - @Parameter(description = "Index of page to be returned") + @Parameter(description = "Index of page to be returned") @BindParam(value = PAGE_NUMBER) @Schema(defaultValue = "0") @PositiveOrZero diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresFilterOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresFilterOptions.java index 03a845bcbfa8966c0bfa3d78945aaf09ef429b41..4e0d304dbf701a320c7e8abc1ae5e6a5a3bc231a 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresFilterOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresFilterOptions.java @@ -8,7 +8,6 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.api.ArchivingApi.QueryParameter.CLOSED_AT_DAY; import static de.eshg.lib.procedure.api.ArchivingApi.QueryParameter.EXPORTED; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import java.time.LocalDate; import org.springdoc.core.annotations.ParameterObject; @@ -16,8 +15,7 @@ import org.springframework.web.bind.annotation.BindParam; @ParameterObject public record GetRelevantArchivableProceduresFilterOptions( - @CanBeLogged - @Parameter( + @Parameter( description = """ Filter logic: @@ -26,8 +24,7 @@ public record GetRelevantArchivableProceduresFilterOptions( """) @BindParam(CLOSED_AT_DAY) LocalDate closedAtDay, - @CanBeLogged - @BindParam(EXPORTED) + @BindParam(EXPORTED) @Parameter( description = """ diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresResponse.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresResponse.java index 3512ef50a977b0075563720e18aa2d30ca0b0709..7ed9fa8090583264943f2d622db7f83640fd7480 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresResponse.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresResponse.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -13,13 +12,9 @@ import jakarta.validation.constraints.Size; import java.util.List; public record GetRelevantArchivableProceduresResponse( - @CanBeLogged - @NotNull - @Schema(description = "Total number of result pages for the given filter criteria") + @NotNull @Schema(description = "Total number of result pages for the given filter criteria") int totalPages, - @CanBeLogged - @NotNull - @Schema(description = "Total number of result elements for the given filter criteria") + @NotNull @Schema(description = "Total number of result elements for the given filter criteria") long totalElements, @Valid @NotNull @Size(max = 200) List<ProcedureDto> procedures, - @CanBeLogged @NotNull int fileSizeBytes) {} + @NotNull int fileSizeBytes) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresSortOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresSortOptions.java index 96da0990309b5e7295d105a02fc4f358ecd451fe..24e9df8f71b6bc1093c8edbd0e1ea2de7089908c 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresSortOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetRelevantArchivableProceduresSortOptions.java @@ -8,15 +8,13 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.api.ArchivingApi.QueryParameter.SORT_BY; import static de.eshg.lib.procedure.api.ArchivingApi.QueryParameter.SORT_ORDER; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema; import java.util.Objects; import org.springframework.web.bind.annotation.BindParam; public record GetRelevantArchivableProceduresSortOptions( - @CanBeLogged - @Parameter( + @Parameter( description = """ The following sorting options are available: @@ -24,12 +22,9 @@ public record GetRelevantArchivableProceduresSortOptions( - `EXPORTED_AT`: Sorting by exportedAt attribute """) @BindParam(SORT_BY) - @Schema(defaultValue = "CREATED_AT") + @Schema(defaultValue = "CLOSED_AT") GetRelevantArchivableProceduresSortByDto sortBy, - @CanBeLogged - @Parameter(description = "Sorting order.") - @BindParam(SORT_ORDER) - @Schema(defaultValue = "ASC") + @Parameter(description = "Sorting order.") @BindParam(SORT_ORDER) @Schema(defaultValue = "ASC") GetRelevantArchivableProceduresSortOrderDto sortOrder) { public GetRelevantArchivableProceduresSortOptions( diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTaskMetricsResponse.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTaskMetricsResponse.java index 1c1a3a2def5913866a684874ebc4e5a51d69931f..256d2790771dad9004b7d47c6a2d2a08010eda8b 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTaskMetricsResponse.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTaskMetricsResponse.java @@ -5,16 +5,15 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.common.BusinessModule; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import java.util.List; public record GetTaskMetricsResponse( - @CanBeLogged @NotNull BusinessModule businessModule, - @CanBeLogged @NotNull ProcedureTypeDto procedureType, - @CanBeLogged @NotNull long closedProcedureCount, + @NotNull BusinessModule businessModule, + @NotNull ProcedureTypeDto procedureType, + @NotNull long closedProcedureCount, @Valid @NotNull List<TaskMetric> taskMetrics, @Valid @NotNull List<ProcedureWithDuration> fastestProcedures, @Valid @NotNull List<ProcedureWithDuration> slowestProcedures) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTasksFilterOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTasksFilterOptions.java index c47bc8489d5d057ef35f61351da3dfcc5521dd33..59908fe146fb40406a1e86845e941e80cca08613 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTasksFilterOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTasksFilterOptions.java @@ -7,7 +7,6 @@ package de.eshg.lib.procedure.model; import static de.eshg.lib.procedure.model.TaskStatusDto.OPEN; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.procedure.api.TaskListApi.QueryParameter; import java.util.Set; import java.util.UUID; @@ -16,11 +15,11 @@ import org.springframework.web.bind.annotation.BindParam; public record GetTasksFilterOptions( @BindParam(QueryParameter.ASSIGNEE_ID) UUID assigneeId, @BindParam(QueryParameter.ASSIGNED_BY_ID) Set<UUID> assignedById, - @CanBeLogged @BindParam(QueryParameter.TASK_TYPE) Set<TaskTypeDto> taskTypes, - @CanBeLogged @BindParam(QueryParameter.TASK_STATUS) Set<TaskStatusDto> taskStatus, - @CanBeLogged @BindParam(QueryParameter.HAS_DUE_AT) Boolean hasDueAt, - @CanBeLogged @BindParam(QueryParameter.IS_OVERDUE) Boolean isOverdue, - @CanBeLogged @BindParam(QueryParameter.WAS_ASSIGNED_BY_OTHER) Boolean wasAssignedByOther) { + @BindParam(QueryParameter.TASK_TYPE) Set<TaskTypeDto> taskTypes, + @BindParam(QueryParameter.TASK_STATUS) Set<TaskStatusDto> taskStatus, + @BindParam(QueryParameter.HAS_DUE_AT) Boolean hasDueAt, + @BindParam(QueryParameter.IS_OVERDUE) Boolean isOverdue, + @BindParam(QueryParameter.WAS_ASSIGNED_BY_OTHER) Boolean wasAssignedByOther) { public static GetTasksFilterOptions forDashboard(UUID assigneeId) { return new GetTasksFilterOptions(assigneeId, null, null, Set.of(OPEN), null, null, null); diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTasksSortOptions.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTasksSortOptions.java index 8486a02e9373c867e184bff3d8fd9bacbc2205cc..1c8cb65449e7b68ab28aad5a6c04dcf8861e8636 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTasksSortOptions.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/GetTasksSortOptions.java @@ -5,15 +5,14 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.procedure.api.TaskListApi.QueryParameter; import jakarta.validation.constraints.NotNull; import java.util.Objects; import org.springframework.web.bind.annotation.BindParam; public record GetTasksSortOptions( - @CanBeLogged @BindParam(QueryParameter.SORT_KEY) @NotNull GetTasksSortByDto sortKey, - @CanBeLogged @BindParam(QueryParameter.SORT_ORDER) GetTasksSortOrderDto sortOrder) { + @BindParam(QueryParameter.SORT_KEY) @NotNull GetTasksSortByDto sortKey, + @BindParam(QueryParameter.SORT_ORDER) GetTasksSortOrderDto sortOrder) { public GetTasksSortOptions(GetTasksSortByDto sortKey, GetTasksSortOrderDto sortOrder) { this.sortKey = sortKey; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ImageMetaDataDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ImageMetaDataDto.java index 691461ba0f898bbcd628b36e627b6e2286369c58..33e5d0df74b63ff060420fc3a10127a31f561e72 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ImageMetaDataDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ImageMetaDataDto.java @@ -6,7 +6,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonTypeName; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import java.time.Instant; @@ -16,7 +15,7 @@ public final class ImageMetaDataDto extends MetaDataDto { public static final String SCHEMA_NAME = "ImageMetaData"; - private @CanBeLogged Instant createdDate; + private Instant createdDate; public Instant getCreatedDate() { return createdDate; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProcedureAddressDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProcedureAddressDto.java index c1fbd198f6ece475b0e6b34a87bcd544eda214de..7315f9de828311352729ade6f97a46d4057d7c7c 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProcedureAddressDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProcedureAddressDto.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; @Schema(name = "InboxProcedureAddress") @@ -14,6 +13,6 @@ public record InboxProcedureAddressDto( String street, String houseNumber, String addressAddition, - @CanBeLogged String postalCode, - @CanBeLogged String city, - @CanBeLogged String country) {} + String postalCode, + String city, + String country) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProcedureDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProcedureDto.java index 9d40f30af44f0777f8cee578179d2847247a3551..2a10e958d1140fa2fd077c2d584d46d82adc1c98 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProcedureDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProcedureDto.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -15,10 +14,10 @@ import java.util.UUID; @Schema(name = "InboxProcedure") public record InboxProcedureDto( @NotNull UUID inboxProcedureId, - @CanBeLogged ProcedureTypeDto inboxProcedureType, - @CanBeLogged @NotNull InboxProcedureStatusDto inboxProcedureStatus, + ProcedureTypeDto inboxProcedureType, + @NotNull InboxProcedureStatusDto inboxProcedureStatus, @NotNull UUID createdBy, - @CanBeLogged @NotNull Instant createdAt, - @CanBeLogged Instant closedAt, + @NotNull Instant createdAt, + Instant closedAt, @Valid @NotNull InboxProgressEntryDto inboxProgressEntry, @Valid @NotNull ContactDetailsDto contactDetails) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProgressEntryDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProgressEntryDto.java index 9dd6f948cf67e6e6d4d420896c7864c132db815c..c835891a61efb249d78f58286813e41e5aaff56e 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProgressEntryDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/InboxProgressEntryDto.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -16,5 +15,5 @@ public record InboxProgressEntryDto( @NotNull UUID inboxProgressEntryId, String subject, String messageText, - @CanBeLogged @NotNull InboxProgressEntryTypeDto inboxProgressEntryType, + @NotNull InboxProgressEntryTypeDto inboxProgressEntryType, @Valid ConcreteFileOrFileReference fileReference) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/MailDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/MailDto.java index 08a131f9178c671a572a1409b698ab09524dd30c..b807fd34cb75595ff44535ef7c832b3141294901 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/MailDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/MailDto.java @@ -7,7 +7,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -24,7 +23,7 @@ public final class MailDto extends ConcreteFileDto { private @Valid List<ConcreteFileDto> attachments; - private @CanBeLogged @NotNull int removedInvalidAttachments; + private @NotNull int removedInvalidAttachments; public MailMetaDataDto getMetaData() { return metaData; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/MailMetaDataDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/MailMetaDataDto.java index c1ff34a3b995b1236734ac4f345fc4113f7db1c2..b757c3463f2416e2bcad92f8d7eb5efe9b8fca53 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/MailMetaDataDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/MailMetaDataDto.java @@ -6,7 +6,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonTypeName; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import java.time.Instant; @@ -19,7 +18,7 @@ public final class MailMetaDataDto extends MetaDataDto { private @NotNull String mailFrom; private @NotNull String mailTo; - private @CanBeLogged @NotNull Instant sentDate; + private @NotNull Instant sentDate; public String getMailFrom() { return mailFrom; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ManualProgressEntryDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ManualProgressEntryDto.java index b3fd698296b181d527ef05306bce6ff85e8d789a..0dbe0f71e824a8b41b52df99d6e4589f89ecbb81 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ManualProgressEntryDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ManualProgressEntryDto.java @@ -6,7 +6,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonTypeName; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.foureyes.model.ApprovalRequestEntityDto; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; @@ -21,13 +20,13 @@ public final class ManualProgressEntryDto extends ProgressEntryDto implements ApprovalRequestEntityDto { public static final String SCHEMA_NAME = "ManualProgressEntry"; - @CanBeLogged @NotNull private ManualProgressEntryTypeDto manualProgressEntryType; + @NotNull private ManualProgressEntryTypeDto manualProgressEntryType; private String subject; private String messageText; private String note; - @CanBeLogged private KeyDocumentTypeDto keyDocumentType; - @CanBeLogged private Integer keyDocumentVersion; - @CanBeLogged @NotNull private boolean locked; + private KeyDocumentTypeDto keyDocumentType; + private Integer keyDocumentVersion; + @NotNull private boolean locked; @NotNull private UUID createdBy; private String createdByUserFirstName; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/PatchManualProgressEntryRequest.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/PatchManualProgressEntryRequest.java index eb5c6cbb5e5e31c359b3c36c20f43e3f949dbf0a..9ffbbaecb74a4e27bf358a191138e21e3fb0217c 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/PatchManualProgressEntryRequest.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/PatchManualProgressEntryRequest.java @@ -5,14 +5,13 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import jakarta.validation.constraints.NotNull; import org.openapitools.jackson.nullable.JsonNullable; public record PatchManualProgressEntryRequest( - @CanBeLogged @NotNull @Schema(requiredMode = RequiredMode.NOT_REQUIRED) + @NotNull @Schema(requiredMode = RequiredMode.NOT_REQUIRED) JsonNullable<ManualProgressEntryTypeDto> manualProgressEntryType, @Schema(nullable = true) JsonNullable<String> subject, @Schema(nullable = true) JsonNullable<String> messageText, diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/PdfMetaDataDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/PdfMetaDataDto.java index 8e7ab6932fb63a5232210f8d2dac1d88f1d4567e..edd97866766b46f28eb241f60a0c9e8fede560b0 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/PdfMetaDataDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/PdfMetaDataDto.java @@ -6,7 +6,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonTypeName; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import java.time.Instant; @@ -16,7 +15,7 @@ public final class PdfMetaDataDto extends MetaDataDto { public static final String SCHEMA_NAME = "PdfMetaData"; - private @CanBeLogged Instant createdDate; + private Instant createdDate; public Instant getCreatedDate() { return createdDate; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureDto.java index d796bd70e6b753850f1336dd47377aa45e1aa26e..4af0ff2dba43f133f6ae5671d0f6450ecde66c9a 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureDto.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.common.BusinessModule; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; @@ -19,13 +18,13 @@ import java.util.UUID; @Valid @Schema(name = "Procedure") public record ProcedureDto( - @CanBeLogged @NotNull BusinessModule businessModule, - @CanBeLogged @NotNull ProcedureTypeDto procedureType, - @CanBeLogged @NotNull Instant createdAt, - @CanBeLogged @NotNull Instant modifiedAt, - @CanBeLogged Instant closedAt, - @CanBeLogged Instant exportedAt, - @CanBeLogged @NotNull ProcedureStatusDto procedureStatus, + @NotNull BusinessModule businessModule, + @NotNull ProcedureTypeDto procedureType, + @NotNull Instant createdAt, + @NotNull Instant modifiedAt, + Instant closedAt, + Instant exportedAt, + @NotNull ProcedureStatusDto procedureStatus, @NotNull UUID procedureId, @Pattern(regexp = "[a-zA-Z0-9.].+") @Size(max = 128) @NotEmpty String summary, @Valid @NotNull ArchivingRelevanceSettingsDto archivingRelevanceSettings) diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureMetric.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureMetric.java index a0740c8da42e6b452db53ac86370eaf484486530..a5c39bd42edc1c08ed6feef3757bd31aa1c0be62 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureMetric.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureMetric.java @@ -5,17 +5,16 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.common.BusinessModule; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; public record ProcedureMetric( - @CanBeLogged @NotNull BusinessModule businessModule, - @CanBeLogged @NotNull ProcedureTypeDto procedureType, - @CanBeLogged @NotNull long totalCount, - @CanBeLogged @NotNull long openOrDraftCount, - @CanBeLogged @NotNull long inProgressCount, - @CanBeLogged @NotNull long abortedCount, - @CanBeLogged @NotNull long closedCount, - @CanBeLogged @Schema(description = "A duration in ISO 8601") String averageDuration) {} + @NotNull BusinessModule businessModule, + @NotNull ProcedureTypeDto procedureType, + @NotNull long totalCount, + @NotNull long openOrDraftCount, + @NotNull long inProgressCount, + @NotNull long abortedCount, + @NotNull long closedCount, + @Schema(description = "A duration in ISO 8601") String averageDuration) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureWithDuration.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureWithDuration.java index a6d5c7fe558d27e6d00662a8e6cd34166a6384c4..99ddb6686d8d6de0502ee5a3fcc656b5245a1cfc 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureWithDuration.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcedureWithDuration.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import java.time.Instant; @@ -13,5 +12,5 @@ import java.util.UUID; public record ProcedureWithDuration( @NotNull UUID id, - @CanBeLogged @NotNull Instant createdAt, - @CanBeLogged @NotNull @Schema(description = "A duration in ISO 8601") String duration) {} + @NotNull Instant createdAt, + @NotNull @Schema(description = "A duration in ISO 8601") String duration) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcessedInboxProgressEntryDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcessedInboxProgressEntryDto.java index 24c27bcd46ba3b8bf9689516045be7227df62772..ae05fa17a9093fed4fcfb0157ea84d1ff0324b87 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcessedInboxProgressEntryDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProcessedInboxProgressEntryDto.java @@ -6,7 +6,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonTypeName; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import java.util.UUID; @@ -17,7 +16,7 @@ public final class ProcessedInboxProgressEntryDto extends ProgressEntryDto { public static final String SCHEMA_NAME = "ProcessedInboxProgressEntry"; @NotNull private UUID inboxProcedureId; - @CanBeLogged @NotNull private InboxProgressEntryTypeDto inboxProgressEntryType; + @NotNull private InboxProgressEntryTypeDto inboxProgressEntryType; private String subject; private String messageText; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProgressEntryDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProgressEntryDto.java index 183cbae11f8f5ca144cd0c306ff19b1cf8732d4b..3ba55d22222f7bd1bb2c76dddee1ef382b1522a1 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProgressEntryDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/ProgressEntryDto.java @@ -7,7 +7,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -19,8 +18,8 @@ import java.util.UUID; public abstract sealed class ProgressEntryDto permits ManualProgressEntryDto, ProcessedInboxProgressEntryDto, SystemProgressEntryDto { @NotNull private UUID progressEntryId; - @CanBeLogged @NotNull private Instant createdAt; - @CanBeLogged @NotNull private Instant modifiedAt; + @NotNull private Instant createdAt; + @NotNull private Instant modifiedAt; private @Valid ConcreteFileOrFileReference fileReference; public UUID getProgressEntryId() { diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/SelfAssignTaskRequest.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/SelfAssignTaskRequest.java index fce7d92f0fb2544f91e6ddad39349bbba242c983..36493bf8e226ebb174fec8febab811ce48208fab 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/SelfAssignTaskRequest.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/SelfAssignTaskRequest.java @@ -5,8 +5,8 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import jakarta.validation.constraints.Future; +import jakarta.validation.constraints.NotNull; import java.time.Instant; -public record SelfAssignTaskRequest(@CanBeLogged @Future Instant dueAt) {} +public record SelfAssignTaskRequest(@NotNull Long taskVersion, @Future Instant dueAt) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/SystemProgressEntryDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/SystemProgressEntryDto.java index 104e84bd43efe67292bdd173fd0380dbb65995b8..71cc179a8bd7e8cbd701457e5e58eb1677d6d090 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/SystemProgressEntryDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/SystemProgressEntryDto.java @@ -6,7 +6,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonTypeName; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import java.util.UUID; @@ -16,8 +15,8 @@ import java.util.UUID; public final class SystemProgressEntryDto extends ProgressEntryDto { public static final String SCHEMA_NAME = "SystemProgressEntry"; - @CanBeLogged @NotNull private String systemProgressEntryType; - @CanBeLogged @NotNull private TriggerTypeDto triggerType; + @NotNull private String systemProgressEntryType; + @NotNull private TriggerTypeDto triggerType; private String changeDescription; private UUID triggeredBy; diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskDto.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskDto.java index 5dc8e41305ff6411252a8ee11aff13ff8551658e..b33420ca3d285c84cedee5cec5cdc2cc734f3c67 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskDto.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskDto.java @@ -6,7 +6,6 @@ package de.eshg.lib.procedure.model; import com.fasterxml.jackson.annotation.JsonIgnore; -import de.eshg.api.commons.CanBeLogged; import de.eshg.lib.common.BusinessModule; import de.eshg.model.HasResolvableUserIds; import io.swagger.v3.oas.annotations.media.Schema; @@ -21,17 +20,18 @@ import java.util.UUID; @Schema(name = "Task") public record TaskDto( @NotNull UUID procedureId, - @CanBeLogged @NotNull BusinessModule businessModule, + @NotNull BusinessModule businessModule, @NotNull UUID taskId, - @CanBeLogged @NotNull Instant createdAt, - @CanBeLogged @NotNull Instant modifiedAt, - @CanBeLogged Instant dueAt, - @CanBeLogged @NotNull boolean isOverdue, + @NotNull Long version, + @NotNull Instant createdAt, + @NotNull Instant modifiedAt, + Instant dueAt, + @NotNull boolean isOverdue, @NotNull @Size(max = 128) String summary, UUID assigneeId, UUID assignedById, - @CanBeLogged @NotNull TaskStatusDto taskStatus, - @CanBeLogged @NotNull TaskTypeDto taskType) + @NotNull TaskStatusDto taskStatus, + @NotNull TaskTypeDto taskType) implements HasResolvableUserIds { @Override @JsonIgnore diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskMetric.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskMetric.java index 3d0743205ac308fffbb6309e207ad97a5754e75c..85139486b43cef80066b221e89d31b1064ece230 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskMetric.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskMetric.java @@ -5,14 +5,13 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; public record TaskMetric( - @CanBeLogged @NotNull TaskTypeDto taskType, - @CanBeLogged @NotNull int noOccurrencesCount, - @CanBeLogged @NotNull int oneOccurrenceCount, - @CanBeLogged @NotNull int twoOccurrencesCount, - @CanBeLogged @NotNull int moreThanTwoOccurrencesCount, - @CanBeLogged @Schema(description = "A duration in ISO 8601") String averageDuration) {} + @NotNull TaskTypeDto taskType, + @NotNull int noOccurrencesCount, + @NotNull int oneOccurrenceCount, + @NotNull int twoOccurrencesCount, + @NotNull int moreThanTwoOccurrencesCount, + @Schema(description = "A duration in ISO 8601") String averageDuration) {} diff --git a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskResponse.java b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskResponse.java index d42c6736d0b2a19cf3d11bf64c14f96ea35506af..7454608ba4752f5be24b94055225dff749f83ad2 100644 --- a/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskResponse.java +++ b/backend/lib-procedures-api/src/main/java/de/eshg/lib/procedure/model/TaskResponse.java @@ -5,7 +5,6 @@ package de.eshg.lib.procedure.model; -import de.eshg.api.commons.CanBeLogged; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -13,5 +12,5 @@ import jakarta.validation.constraints.Size; import java.util.List; public record TaskResponse( - @CanBeLogged @NotNull @Schema(description = "total number of tasks for this query") long count, + @NotNull @Schema(description = "total number of tasks for this query") long count, @NotNull @Size(max = 200) @Valid List<TaskDto> tasks) {} diff --git a/backend/lib-procedures/gradle.lockfile b/backend/lib-procedures/gradle.lockfile index 8969fdfa59811a2eea8654ee264d3a2262fa99a0..90acea066128201879a4c1af3c945c1f0c0df722 100644 --- a/backend/lib-procedures/gradle.lockfile +++ b/backend/lib-procedures/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.adobe.xmp:xmpcore:6.1.11=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.drewnoakes:metadata-extractor:2.19.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -25,8 +25,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.h2database:h2:2.2.224=testRuntimeClasspath @@ -51,7 +52,7 @@ com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeCla commons-codec:commons-codec:1.16.1=testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.15.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-logging:commons-logging:1.3.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -59,11 +60,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -71,14 +72,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,xjc jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath,xjc @@ -111,10 +111,10 @@ org.apache.tika:tika-bom:2.9.2=compileClasspath,productionRuntimeClasspath,runti org.apache.tika:tika-core:2.9.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.tika:tika-parser-pdf-module:2.9.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.tika:tika-parser-xmp-commons:2.9.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -136,9 +136,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.instancio:instancio-core:5.0.2=testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt @@ -166,7 +166,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -174,30 +174,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -207,19 +207,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath diff --git a/backend/lib-procedures/openApi.yaml b/backend/lib-procedures/openApi.yaml index e89db0d0b8ef9d7573c39f36eb3d2d8cfe9a41a8..0cd853290e68bb753ebd58395ba254008fc2482c 100644 --- a/backend/lib-procedures/openApi.yaml +++ b/backend/lib-procedures/openApi.yaml @@ -1654,8 +1654,12 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 required: - assignee + - taskVersion BulkUpdateProceduresArchivingRelevanceRequest: type: object properties: @@ -2411,7 +2415,7 @@ components: - totalPages GetArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - PROCEDURE_TYPE @@ -2748,7 +2752,7 @@ components: - totalPages GetRelevantArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - EXPORTED_AT @@ -3542,6 +3546,11 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 + required: + - taskVersion SystemProgressEntry: type: object allOf: @@ -3603,6 +3612,9 @@ components: $ref: "#/components/schemas/TaskStatus" taskType: $ref: "#/components/schemas/TaskType" + version: + type: integer + format: int64 required: - businessModule - createdAt @@ -3613,6 +3625,7 @@ components: - taskId - taskStatus - taskType + - version TaskMetric: type: object properties: diff --git a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/domain/repository/TaskRepository.java b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/domain/repository/TaskRepository.java index fd5f6ba3061f70ed163881210b4a8c932e9a5f9a..8d9fdcb0fc83cd9c96967b2b8c0831237c938a2d 100644 --- a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/domain/repository/TaskRepository.java +++ b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/domain/repository/TaskRepository.java @@ -10,6 +10,7 @@ import de.eshg.lib.procedure.domain.model.ProcedureType; import de.eshg.lib.procedure.domain.model.Task; import de.eshg.lib.procedure.domain.model.TaskDueAtReminderNotification; import de.eshg.lib.procedure.domain.model.TaskType; +import jakarta.persistence.LockModeType; import java.time.Duration; import java.time.Instant; import java.util.List; @@ -19,6 +20,7 @@ import java.util.UUID; import java.util.stream.Stream; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.repository.query.Param; @@ -29,6 +31,10 @@ public interface TaskRepository<TaskT extends Task<? extends Procedure<?, TaskT, Optional<TaskT> findByExternalId(UUID externalId); + @Query("SELECT task FROM #{#entityName} task WHERE task.externalId = :externalId") + @Lock(LockModeType.PESSIMISTIC_WRITE) + Optional<TaskT> findByExternalIdForUpdate(@Param("externalId") UUID externalId); + @Query( """ SELECT task FROM #{#entityName} task diff --git a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/domain/serialization/ZipFileWrapper.java b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/domain/serialization/ZipFileWrapper.java index cb5f2dcabb1097e871ef17396cb347d0032a32d7..15ff47b5a1289a0ce455ec311730be43067569db 100644 --- a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/domain/serialization/ZipFileWrapper.java +++ b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/domain/serialization/ZipFileWrapper.java @@ -8,7 +8,7 @@ package de.eshg.lib.procedure.domain.serialization; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UncheckedIOException; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.zip.ZipEntry; @@ -17,7 +17,7 @@ import org.apache.commons.io.FilenameUtils; public class ZipFileWrapper { - private final Map<String, byte[]> entries = new HashMap<>(); + private final Map<String, byte[]> entries = new LinkedHashMap<>(); public String getCollisionFreeFileName(String originalFileName) { int number = 0; @@ -35,13 +35,15 @@ public class ZipFileWrapper { } public byte[] asByteArray() { - try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) { - for (Entry<String, byte[]> file : entries.entrySet()) { - zipOutputStream.putNextEntry(new ZipEntry(file.getKey())); - zipOutputStream.write(file.getValue()); - zipOutputStream.closeEntry(); + try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) { + for (Entry<String, byte[]> file : entries.entrySet()) { + zipOutputStream.putNextEntry(new ZipEntry(file.getKey())); + zipOutputStream.write(file.getValue()); + zipOutputStream.closeEntry(); + } } + return byteArrayOutputStream.toByteArray(); } catch (IOException e) { throw new UncheckedIOException("Error during creating zip file", e); diff --git a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/housekeeping/archiving/ArchivingController.java b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/housekeeping/archiving/ArchivingController.java index a729770830abe546d8a646e08946ef8d30b274d6..0e67d778da69a1c357c4aff07d328497ba6bb70e 100644 --- a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/housekeeping/archiving/ArchivingController.java +++ b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/housekeeping/archiving/ArchivingController.java @@ -14,6 +14,10 @@ import static de.eshg.lib.procedure.domain.model.Procedure_.archivingRelevance; import static de.eshg.lib.procedure.domain.model.Procedure_.closedAt; import static de.eshg.lib.procedure.domain.model.Procedure_.exportedAt; import static de.eshg.lib.procedure.domain.model.Procedure_.procedureType; +import static java.time.format.DateTimeFormatter.ISO_LOCAL_DATE; +import static java.time.temporal.ChronoField.HOUR_OF_DAY; +import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; +import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; import static org.springframework.data.domain.PageRequest.ofSize; import static org.springframework.data.jpa.domain.Specification.where; import static org.springframework.http.HttpHeaders.CONTENT_DISPOSITION; @@ -29,6 +33,7 @@ import de.eshg.lib.procedure.domain.model.Procedure; import de.eshg.lib.procedure.domain.model.ProcedureType; import de.eshg.lib.procedure.domain.model.Task; import de.eshg.lib.procedure.domain.repository.ProcedureRepository; +import de.eshg.lib.procedure.domain.serialization.SerializationService; import de.eshg.lib.procedure.domain.specification.ArchivableProceduresSpecification; import de.eshg.lib.procedure.mapping.ProcedureLibraryEnrichingMapper; import de.eshg.lib.procedure.mapping.ProcedureMapper; @@ -51,20 +56,19 @@ import de.eshg.lib.procedure.model.GetRelevantArchivableProceduresSortOptions; import de.eshg.lib.procedure.model.GetRelevantArchivableProceduresSortOrderDto; import de.eshg.lib.procedure.model.ProcedureTypeDto; import io.swagger.v3.oas.annotations.tags.Tag; -import java.io.IOException; import java.nio.charset.StandardCharsets; import java.time.Clock; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; -import org.springframework.core.io.ClassPathResource; import org.springframework.data.domain.Page; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; @@ -81,13 +85,27 @@ public class ArchivingController< ProcedureT extends Procedure<ProcedureT, TaskT, ?, ?>, TaskT extends Task<ProcedureT>> implements ArchivingApi { - private static final String ARCHIVE_EXPORT_FILE_NAME_TEMPLATE = "Archiv-Vorgangsexport_%s"; - private static final String CONTENT_DISPOSITION_NAME_JSON = "json"; + private static final DateTimeFormatter ARCHIVE_EXPORT_DATE_TIME_FORMATTER = + new DateTimeFormatterBuilder() + .parseCaseInsensitive() + .append(ISO_LOCAL_DATE) + .appendLiteral('T') + .appendValue(HOUR_OF_DAY, 2) + .appendLiteral('-') + .appendValue(MINUTE_OF_HOUR, 2) + .optionalStart() + .appendLiteral('-') + .appendValue(SECOND_OF_MINUTE, 2) + .toFormatter(); + + private static final String ARCHIVE_EXPORT_FILE_NAME_TEMPLATE = "Archiv-Vorgangsexport_%s.zip"; + private static final String ARCHIVE_EXPORT_ZIP_ENTRY_NAME_TEMPLATE = "Archiv-Vorgang_"; private static final String CONTENT_DISPOSITION_NAME_ZIP = "zip"; private final ProcedureLibraryEnrichingMapper<ProcedureT, TaskT> enrichingMapper; private final ProcedureRepository<ProcedureT> procedureRepository; private final ArchivableProceduresSpecification<ProcedureT> archivableProceduresSpecification; private final ArchivingProperties archivingProperties; + private final SerializationService serializationService; private final Clock clock; public ArchivingController( @@ -95,11 +113,13 @@ public class ArchivingController< ProcedureRepository<ProcedureT> procedureRepository, ArchivableProceduresSpecification<ProcedureT> archivableProceduresSpecification, ArchivingProperties archivingProperties, + SerializationService serializationService, Clock clock) { this.enrichingMapper = enrichingMapper; this.procedureRepository = procedureRepository; this.archivableProceduresSpecification = archivableProceduresSpecification; this.archivingProperties = archivingProperties; + this.serializationService = serializationService; this.clock = clock; } @@ -290,10 +310,11 @@ public class ArchivingController< @Override @Transactional public ResponseEntity<byte[]> exportRelevantProcedures( - ExportArchivingRelevantProceduresRequest request) throws IOException { + ExportArchivingRelevantProceduresRequest request) { List<ProcedureT> procedures = procedureRepository.findAll( - where(archivingRelevanceRelevant()).and(externalIds(request.procedures()))); + where(archivingRelevanceRelevant()).and(externalIds(request.procedures())), + Sort.by(Direction.ASC, CLOSED_AT, ID)); Instant now = Instant.now(clock); @@ -304,19 +325,14 @@ public class ArchivingController< return ResponseEntity.ok() .contentType(CustomMediaTypes.ZIP) .header(CONTENT_DISPOSITION, getContentDisposition(now).toString()) - .body(getZipDummy()); - } - - private byte[] getZipDummy() throws IOException { - ClassPathResource classPathResource = new ClassPathResource("dummy.zip"); - return classPathResource.getContentAsByteArray(); + .body(serializationService.toNestedZip(ARCHIVE_EXPORT_ZIP_ENTRY_NAME_TEMPLATE, procedures)); } private ContentDisposition getContentDisposition(Instant now) { String fileName = ARCHIVE_EXPORT_FILE_NAME_TEMPLATE.formatted( LocalDateTime.ofInstant(now, clock.getZone()) - .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); + .format(ARCHIVE_EXPORT_DATE_TIME_FORMATTER)); return ContentDisposition.attachment() .name(CONTENT_DISPOSITION_NAME_ZIP) @@ -325,6 +341,7 @@ public class ArchivingController< } @Override + @Transactional(readOnly = true) public GetArchivingConfigurationResponse getArchivingConfiguration() { return new GetArchivingConfigurationResponse( archivingProperties.getGracePeriodMonths(), getArchivingProperties()); diff --git a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/mapping/TaskMapper.java b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/mapping/TaskMapper.java index 80b0dc161ed376da712896b5bb3a79ae6f418ae7..07f7f85d2906f96f4cd52c4c9b2de544c1f34668 100644 --- a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/mapping/TaskMapper.java +++ b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/mapping/TaskMapper.java @@ -33,6 +33,7 @@ public final class TaskMapper { domainModelTask.getProcedure().getExternalId(), businessModule, domainModelTask.getExternalId(), + domainModelTask.getVersion(), domainModelTask.getCreatedAt(), domainModelTask.getModifiedAt(), domainModelTask.getDueAt(), diff --git a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/procedures/ProcedureController.java b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/procedures/ProcedureController.java index 8f99f16db7210c65b3184657f43f3b811667acfe..80497cfea62e031194c1e5a06b621ea1846d7ac2 100644 --- a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/procedures/ProcedureController.java +++ b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/procedures/ProcedureController.java @@ -315,7 +315,8 @@ public class ProcedureController< fileDeletionApprovalRequestRoot.get(FileDeletionApprovalRequest_.file); Root<ProgressEntry> progressEntryRoot = query.from(ProgressEntry.class); - Join<ProgressEntry, File> progressEntryFile = progressEntryRoot.join(ProgressEntry_.file); + Join<ProgressEntry, File> progressEntryFile = + progressEntryRoot.join(ProgressEntry_.file, JoinType.LEFT); return cb.and( cb.equal(progressEntryFile, approvalRequestFile), diff --git a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/tasks/TaskController.java b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/tasks/TaskController.java index 428b3310fbd10c0c0219e457bdd0b92263907264..10d50c7d215266745e61f62353cedec10c18f39e 100644 --- a/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/tasks/TaskController.java +++ b/backend/lib-procedures/src/main/java/de/eshg/lib/procedure/tasks/TaskController.java @@ -36,6 +36,7 @@ import de.eshg.lib.procedure.util.MetricTimeRangeValidator; import de.eshg.rest.service.error.BadRequestException; import de.eshg.rest.service.error.NotFoundException; import de.eshg.rest.service.security.CurrentUserHelper; +import de.eshg.validation.ValidationUtil; import io.swagger.v3.oas.annotations.tags.Tag; import java.time.Clock; import java.time.Duration; @@ -121,13 +122,18 @@ public class TaskController< public TaskDto assignTask(UUID taskId, AssignTaskRequest assignTaskRequest) { UUID assigneeId = assignTaskRequest.assignee(); validateUserExists(assigneeId); - return assignTask(taskId, assigneeId, assignTaskRequest.dueAt()); + return assignTask( + taskId, assignTaskRequest.taskVersion(), assigneeId, assignTaskRequest.dueAt()); } @Transactional @Override public TaskDto selfAssignTask(UUID taskId, SelfAssignTaskRequest assignTaskRequest) { - return assignTask(taskId, CurrentUserHelper.getCurrentUserId(), assignTaskRequest.dueAt()); + return assignTask( + taskId, + assignTaskRequest.taskVersion(), + CurrentUserHelper.getCurrentUserId(), + assignTaskRequest.dueAt()); } @Override @@ -136,18 +142,22 @@ public class TaskController< return taskTeamOverviewService.getTasksByAssignee(assignee); } - private TaskDto assignTask(UUID taskId, UUID assigneeId, Instant dueAt) { - TaskT task = getTaskOrThrow(taskId); + private TaskDto assignTask(UUID taskId, Long taskVersion, UUID assigneeId, Instant dueAt) { + TaskT task = getTaskForUpdateOrThrow(taskId, taskVersion); task.assign(assigneeId, CurrentUserHelper.getCurrentUserId(), Instant.now(clock)); task.updateDueAt(dueAt); taskRepository.flush(); return enrichingMapper.enrichAndMap(task); } - private TaskT getTaskOrThrow(UUID taskId) { - return taskRepository - .findByExternalId(taskId) - .orElseThrow(() -> new NotFoundException("Task not found")); + private TaskT getTaskForUpdateOrThrow(UUID taskId, Long taskVersion) { + TaskT task = + taskRepository + .findByExternalIdForUpdate(taskId) + .orElseThrow(() -> new NotFoundException("Task not found")); + + ValidationUtil.validateVersion(taskVersion, task); + return task; } private void validateUserExists(UUID userId) { diff --git a/backend/lib-procedures/src/main/resources/dummy.zip b/backend/lib-procedures/src/main/resources/dummy.zip deleted file mode 100644 index a9484a95ccf0b70b0a9cf4a0b16791ef9ce1b8f4..0000000000000000000000000000000000000000 Binary files a/backend/lib-procedures/src/main/resources/dummy.zip and /dev/null differ diff --git a/backend/lib-relay/build.gradle b/backend/lib-relay/build.gradle index 5e8df0dd186cbd5d7eebb8b3286527191938d958..105fec5a39789a52c302ffa09d6035add642f161 100644 --- a/backend/lib-relay/build.gradle +++ b/backend/lib-relay/build.gradle @@ -9,6 +9,7 @@ dependencies { testImplementation project(':test-commons') testFixturesImplementation project(':test-commons') + testFixturesImplementation project(':test-helper-commons-spring') testFixturesApi testFixtures(project(':lib-service-directory-admin-api')) testFixturesApi 'org.testcontainers:testcontainers' } diff --git a/backend/lib-relay/gradle.lockfile b/backend/lib-relay/gradle.lockfile index edfc0cdd2b7b8b264bbadb8fe8ce4efcf4621883..9c591f0654775bf1deba13e2552e6c2b32da0b93 100644 --- a/backend/lib-relay/gradle.lockfile +++ b/backend/lib-relay/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=testFixturesRuntimeClasspath,testRuntimeClasspath @@ -16,8 +16,9 @@ com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.9.2=testFixtures com.google.code.findbugs:jsr305:3.0.2=testFixturesRuntimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.sun.istack:istack-commons-runtime:4.1.2=testFixturesRuntimeClasspath,testRuntimeClasspath @@ -27,15 +28,15 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testFixturesRuntimeClasspath,t com.tngtech.archunit:archunit-junit5:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testFixturesRuntimeClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=testFixturesRuntimeClasspath,testRuntimeClasspath @@ -69,7 +70,7 @@ org.glassfish.jaxb:txw2:4.0.5=testFixturesRuntimeClasspath,testRuntimeClasspath org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=testFixturesRuntimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=testFixturesRuntimeClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt @@ -91,31 +92,31 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testFixturesCompileClasspat org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testFixturesRuntimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testFixturesRuntimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath diff --git a/backend/lib-relay/src/testFixtures/java/de/eshg/relayserver/testcontainers/RelayServerTestContainerUtil.java b/backend/lib-relay/src/testFixtures/java/de/eshg/relayserver/testcontainers/RelayServerTestContainerUtil.java index 1f680184e99dedbdfc29ba6727a6f59b91c59f35..7f7cb301f3a3dc0307559869f7abeea2ed2feb14 100644 --- a/backend/lib-relay/src/testFixtures/java/de/eshg/relayserver/testcontainers/RelayServerTestContainerUtil.java +++ b/backend/lib-relay/src/testFixtures/java/de/eshg/relayserver/testcontainers/RelayServerTestContainerUtil.java @@ -5,6 +5,8 @@ package de.eshg.relayserver.testcontainers; +import static de.eshg.testhelper.ConditionalOnTestHelperEnabled.TEST_HELPER_PROFILE_NAME; + import de.eshg.base.TestContainersUtil; import de.eshg.servicedirectory.testcontainers.ServiceDirectoryTestContainerUtil; import org.springframework.test.context.DynamicPropertyRegistry; @@ -29,7 +31,7 @@ public class RelayServerTestContainerUtil { .withExposedPorts(RS_PORT) .dependsOn(serviceDirectory.container()) .withEnv("SERVER_PORT", Integer.toString(RS_PORT)) - .withEnv("spring.profiles.active", "test-helper") + .withEnv("spring.profiles.active", TEST_HELPER_PROFILE_NAME) .withEnv( "eshg.servicedirectory.baseUrl", ServiceDirectoryTestContainerUtil.getServiceUrl(serviceDirectory.container())) diff --git a/backend/lib-security-config-urls/gradle.lockfile b/backend/lib-security-config-urls/gradle.lockfile index b7630d8cdd1cd872bfe2c81f1f31ea500a7e24fb..0dccf585508f79ea672a181febfba0ac3e39fbf0 100644 --- a/backend/lib-security-config-urls/gradle.lockfile +++ b/backend/lib-security-config-urls/gradle.lockfile @@ -1,12 +1,12 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testRuntimeClasspath @@ -42,20 +42,20 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,compileClasspath,developmentOnly,productionRuntimeClasspath,runtimeClasspath,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-security-config-urls/src/main/java/de/eshg/rest/service/security/config/BaseUrls.java b/backend/lib-security-config-urls/src/main/java/de/eshg/rest/service/security/config/BaseUrls.java index c409fb22014719d45c742f0f28e9be290a9832fd..7dd5181a5c8bc4d943cf78dd84f26b55d261443f 100644 --- a/backend/lib-security-config-urls/src/main/java/de/eshg/rest/service/security/config/BaseUrls.java +++ b/backend/lib-security-config-urls/src/main/java/de/eshg/rest/service/security/config/BaseUrls.java @@ -57,6 +57,7 @@ public final class BaseUrls { public static final String DEPARTMENT_API_INFO = "/info"; public static final String DEPARTMENT_API_LOGO = "/logo"; public static final String DEPARTMENT_API_SECURITY_TXT = "/security-txt"; + public static final String DEPARTMENT_API_SECURITY_TXT_PGP_KEY = "/security-txt-public-key"; public static final String CONTACT_PARSE_VCARD_URL = "/parse-vcard"; public static final String GDPR_PROCEDURE_API = "/gdpr-procedures"; public static final String FACILITY_API = "/facilities"; @@ -155,6 +156,8 @@ public final class BaseUrls { public static final class AuditLog { public static final String AUDIT_LOG_CONTROLLER = "/auditlog"; + public static final String FEATURE_TOGGLES_CONTROLLER = "/feature-toggles"; + private AuditLog() {} } diff --git a/backend/lib-security-config/gradle.lockfile b/backend/lib-security-config/gradle.lockfile index 09ba5b1d3933715923a06db49d189b7a56d98a8c..e62dc76d86a03c44edf0223ea4d345ca547dfde2 100644 --- a/backend/lib-security-config/gradle.lockfile +++ b/backend/lib-security-config/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=testRuntimeClasspath @@ -16,8 +16,9 @@ com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.9.2=testRuntimeC com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.sun.istack:istack-commons-runtime:4.1.2=testRuntimeClasspath @@ -27,15 +28,15 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=testRuntimeClasspath @@ -69,7 +70,7 @@ org.glassfish.jaxb:txw2:4.0.5=testRuntimeClasspath org.hamcrest:hamcrest-core:2.2=testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt @@ -91,33 +92,33 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=testRuntimeClasspath org.testcontainers:testcontainers:1.19.8=testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath diff --git a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/AbstractPublicSecurityConfiguration.java b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/AbstractPublicSecurityConfiguration.java index 0a52b641b1bbf0a81cdad3dc35cab2eb153b21ef..a5d1fed49f3e4c3333517286f8bcd7f29ed05458 100644 --- a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/AbstractPublicSecurityConfiguration.java +++ b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/AbstractPublicSecurityConfiguration.java @@ -76,12 +76,18 @@ public abstract class AbstractPublicSecurityConfiguration { } } - protected void grantAccessToLibAppointmentBlockUrls(PermissionRole permissionRole) { + protected void grantAccessToLibAppointmentBlockUrls( + PermissionRole permissionRole, boolean allowUpdateAppointmentType) { requestMatchers(BaseUrls.LibAppointmentBlock.APPOINTMENT_BLOCK_API + "/**") .hasRole(permissionRole); - requestMatchers(BaseUrls.LibAppointmentBlock.APPOINTMENT_TYPE_API + "/**") - .hasRole(permissionRole); + if (allowUpdateAppointmentType) { + requestMatchers(BaseUrls.LibAppointmentBlock.APPOINTMENT_TYPE_API + "/**") + .hasRole(permissionRole); + } else { + requestMatchers(HttpMethod.GET, BaseUrls.LibAppointmentBlock.APPOINTMENT_TYPE_API + "/**") + .hasRole(permissionRole); + } } protected void grantAccessToLibProceduresUrls( diff --git a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/AuditlogPublicSecurityConfig.java b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/AuditlogPublicSecurityConfig.java index 05247eab299f5df9b90ebe5798b3633fb426e073..1b6a75ceab1f865b83faf2fc99cdd54500ac1292 100644 --- a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/AuditlogPublicSecurityConfig.java +++ b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/AuditlogPublicSecurityConfig.java @@ -19,7 +19,9 @@ public final class AuditlogPublicSecurityConfig extends AbstractPublicSecurityCo .hasRole(EmployeePermissionRole.AUDITLOG_DECRYPT_AND_ACCESS); requestMatchers(HttpMethod.GET, AuditLog.AUDIT_LOG_CONTROLLER + "/key") .hasRole(EmployeePermissionRole.AUDITLOG_DECRYPT_AND_ACCESS); - requestMatchers(HttpMethod.GET, AuditLog.AUDIT_LOG_CONTROLLER + "/grantees") + requestMatchers(HttpMethod.GET, AuditLog.AUDIT_LOG_CONTROLLER + "/grantees-candidates") + .hasRole(EmployeePermissionRole.AUDITLOG_AUTHORIZE_ACCESS); + requestMatchers(HttpMethod.GET, AuditLog.AUDIT_LOG_CONTROLLER + "/grant-access") .hasRole(EmployeePermissionRole.AUDITLOG_AUTHORIZE_ACCESS); requestMatchers(HttpMethod.POST, AuditLog.AUDIT_LOG_CONTROLLER + "/grant-access") .hasRole(EmployeePermissionRole.AUDITLOG_AUTHORIZE_ACCESS); @@ -27,5 +29,7 @@ public final class AuditlogPublicSecurityConfig extends AbstractPublicSecurityCo .hasRole(EmployeePermissionRole.AUDITLOG_AUTHORIZE_ACCESS); requestMatchers(HttpMethod.GET, AuditLog.AUDIT_LOG_CONTROLLER + "/accessible") .hasRole(EmployeePermissionRole.AUDITLOG_DECRYPT_AND_ACCESS); + requestMatchers(BaseUrls.AuditLog.FEATURE_TOGGLES_CONTROLLER + "/**") + .hasRole(EmployeePermissionRole.STANDARD_EMPLOYEE); } } diff --git a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/BasePublicSecurityConfig.java b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/BasePublicSecurityConfig.java index c9c84b3e5181122ce57bdda2e6b03ad3f38470cc..61399343dfa0b06e938a15b7a1bc04b455a12dd2 100644 --- a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/BasePublicSecurityConfig.java +++ b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/BasePublicSecurityConfig.java @@ -218,6 +218,9 @@ public final class BasePublicSecurityConfig extends AbstractPublicSecurityConfig .permitAll(); requestMatchers(GET, BaseUrls.Base.DEPARTMENT_API + BaseUrls.Base.DEPARTMENT_API_SECURITY_TXT) .permitAll(); + requestMatchers( + GET, BaseUrls.Base.DEPARTMENT_API + BaseUrls.Base.DEPARTMENT_API_SECURITY_TXT_PGP_KEY) + .permitAll(); } private void features() { diff --git a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/MeaslesProtectionPublicSecurityConfig.java b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/MeaslesProtectionPublicSecurityConfig.java index 4df28d6dec0237f8a276b36c64b71e4a442ee77b..c2506af0d0801f899f9ef4a7cc8989f250485784 100644 --- a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/MeaslesProtectionPublicSecurityConfig.java +++ b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/MeaslesProtectionPublicSecurityConfig.java @@ -17,7 +17,7 @@ public final class MeaslesProtectionPublicSecurityConfig MeaslesProtectionPublicSecurityConfig() { super("measles-protection"); - grantAccessToLibAppointmentBlockUrls(EmployeePermissionRole.MEASLES_PROTECTION_ADMIN); + grantAccessToLibAppointmentBlockUrls(EmployeePermissionRole.MEASLES_PROTECTION_ADMIN, true); grantAccessToLibProceduresUrls( EmployeePermissionRole.MEASLES_PROTECTION_ADMIN, ModuleLeaderRole.MEASLES_PROTECTION_LEADER); diff --git a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/SchoolEntryPublicSecurityConfig.java b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/SchoolEntryPublicSecurityConfig.java index 6594600aefc13cac6bf70fcbbe0aeb0c84d5112c..1370aa0f617e19bf7a9db6f6fd4de48562fa482c 100644 --- a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/SchoolEntryPublicSecurityConfig.java +++ b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/SchoolEntryPublicSecurityConfig.java @@ -15,7 +15,7 @@ public final class SchoolEntryPublicSecurityConfig extends AbstractPublicSecurit SchoolEntryPublicSecurityConfig() { super("school-entry"); - grantAccessToLibAppointmentBlockUrls(EmployeePermissionRole.SCHOOL_ENTRY_ADMIN); + grantAccessToLibAppointmentBlockUrls(EmployeePermissionRole.SCHOOL_ENTRY_ADMIN, false); grantAccessToStatistics(); grantAccessToLibProceduresUrls( EmployeePermissionRole.SCHOOL_ENTRY_ADMIN, ModuleLeaderRole.SCHOOL_ENTRY_LEADER); diff --git a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/StiProtectionPublicSecurityConfig.java b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/StiProtectionPublicSecurityConfig.java index 243c8613fa17390c48e0173e3d33048abf3c94ae..39ee7fd7361accabb683ff804c2c5a0ac0b7f417 100644 --- a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/StiProtectionPublicSecurityConfig.java +++ b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/StiProtectionPublicSecurityConfig.java @@ -14,7 +14,7 @@ public final class StiProtectionPublicSecurityConfig extends AbstractPublicSecur StiProtectionPublicSecurityConfig() { super("sti-protection"); - grantAccessToLibAppointmentBlockUrls(EmployeePermissionRole.STI_PROTECTION_USER); + grantAccessToLibAppointmentBlockUrls(EmployeePermissionRole.STI_PROTECTION_USER, true); grantAccessToLibProceduresUrls( EmployeePermissionRole.STI_PROTECTION_USER, ModuleLeaderRole.STI_PROTECTION_LEADER); diff --git a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/TravelMedicinePublicSecurityConfig.java b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/TravelMedicinePublicSecurityConfig.java index f5c22badf8bc4c5260ce420b5da4e51332aadc1a..1c2e40cdf4c3ad7e14f47329859e7817a1e64e32 100644 --- a/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/TravelMedicinePublicSecurityConfig.java +++ b/backend/lib-security-config/src/main/java/de/eshg/rest/service/security/config/TravelMedicinePublicSecurityConfig.java @@ -15,7 +15,7 @@ public final class TravelMedicinePublicSecurityConfig extends AbstractPublicSecu TravelMedicinePublicSecurityConfig() { super("travel-medicine"); - grantAccessToLibAppointmentBlockUrls(EmployeePermissionRole.TRAVEL_MEDICINE_ADMIN); + grantAccessToLibAppointmentBlockUrls(EmployeePermissionRole.TRAVEL_MEDICINE_ADMIN, true); grantAccessToLibProceduresUrls( EmployeePermissionRole.TRAVEL_MEDICINE_ADMIN, ModuleLeaderRole.TRAVEL_MEDICINE_LEADER); diff --git a/backend/lib-service-directory-admin-api/build.gradle b/backend/lib-service-directory-admin-api/build.gradle index fac813e29b829c1ee12d7619820a8397dc9d3574..b1e210e82a058d0381c75a75aef991be002baaef 100644 --- a/backend/lib-service-directory-admin-api/build.gradle +++ b/backend/lib-service-directory-admin-api/build.gradle @@ -8,8 +8,10 @@ dependencies { api project(':test-helper-commons-api') api 'org.springframework.security:spring-security-core' implementation 'org.springframework.boot:spring-boot-autoconfigure' + implementation project(':test-helper-commons-spring') testFixturesImplementation project(':test-commons') + testFixturesImplementation project(':test-helper-commons-spring') testFixturesImplementation 'org.testcontainers:postgresql' testFixturesApi 'org.testcontainers:testcontainers' testFixturesApi 'org.springframework:spring-test' diff --git a/backend/lib-service-directory-admin-api/gradle.lockfile b/backend/lib-service-directory-admin-api/gradle.lockfile index b0c92e16a904ff833de1aac0178c70fe888cb0d2..a62bb9d4bc1570a291794937d3b510fdbb46ff8e 100644 --- a/backend/lib-service-directory-admin-api/gradle.lockfile +++ b/backend/lib-service-directory-admin-api/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=testFixturesRuntimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=testFixturesRuntimeClasspath,testRuntimeClasspath @@ -16,8 +16,9 @@ com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.9.2=testFixtures com.google.code.findbugs:jsr305:3.0.2=testFixturesRuntimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=testFixturesRuntimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=testFixturesRuntimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.sun.istack:istack-commons-runtime:4.1.2=testFixturesRuntimeClasspath,testRuntimeClasspath @@ -27,15 +28,15 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testFixturesRuntimeClasspath,t com.tngtech.archunit:archunit-junit5:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testFixturesRuntimeClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=testFixturesRuntimeClasspath,testRuntimeClasspath @@ -69,7 +70,7 @@ org.glassfish.jaxb:txw2:4.0.5=testFixturesRuntimeClasspath,testRuntimeClasspath org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=testFixturesRuntimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=testFixturesRuntimeClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt @@ -91,31 +92,31 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testFixturesCompileClasspat org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testFixturesRuntimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testFixturesRuntimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath diff --git a/backend/lib-service-directory-admin-api/src/main/java/de/eshg/libservicedirectoryadminapi/ServiceDirectoryAdminApiConfiguration.java b/backend/lib-service-directory-admin-api/src/main/java/de/eshg/libservicedirectoryadminapi/ServiceDirectoryAdminApiConfiguration.java index 8ddc35c8af64799b9df230a0c08dd9be5a99b0c7..a10eb12031d895e2c0de693451344f98f0e9bed5 100644 --- a/backend/lib-service-directory-admin-api/src/main/java/de/eshg/libservicedirectoryadminapi/ServiceDirectoryAdminApiConfiguration.java +++ b/backend/lib-service-directory-admin-api/src/main/java/de/eshg/libservicedirectoryadminapi/ServiceDirectoryAdminApiConfiguration.java @@ -6,10 +6,7 @@ package de.eshg.libservicedirectoryadminapi; import de.eshg.libservicedirectoryadminapi.api.testhelper.ServiceDirectoryTestHelperApi; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import de.eshg.testhelper.ConditionalOnTestHelperEnabled; import java.time.Duration; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -18,7 +15,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.client.ClientHttpRequestFactories; import org.springframework.boot.web.client.ClientHttpRequestFactorySettings; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Profile; import org.springframework.web.client.RestClient; import org.springframework.web.client.RestClient.Builder; import org.springframework.web.client.support.RestClientAdapter; @@ -56,10 +52,4 @@ public class ServiceDirectoryAdminApiConfiguration { return httpServiceProxyFactory.createClient(api); } - - // TODO: replace this with common import - @Target({ElementType.TYPE, ElementType.METHOD}) - @Retention(RetentionPolicy.RUNTIME) - @Profile("test-helper") - public @interface ConditionalOnTestHelperEnabled {} } diff --git a/backend/lib-service-directory-admin-api/src/testFixtures/java/de/eshg/servicedirectory/testcontainers/ServiceDirectoryTestContainerUtil.java b/backend/lib-service-directory-admin-api/src/testFixtures/java/de/eshg/servicedirectory/testcontainers/ServiceDirectoryTestContainerUtil.java index a78f4ac3b35010f86549391490d2d230b6d225f2..baf32afb7d3756ffde7add87dd445a7664ab32b4 100644 --- a/backend/lib-service-directory-admin-api/src/testFixtures/java/de/eshg/servicedirectory/testcontainers/ServiceDirectoryTestContainerUtil.java +++ b/backend/lib-service-directory-admin-api/src/testFixtures/java/de/eshg/servicedirectory/testcontainers/ServiceDirectoryTestContainerUtil.java @@ -6,6 +6,7 @@ package de.eshg.servicedirectory.testcontainers; import static de.eshg.base.PostgresContainerConstants.POSTGRES_PORT; +import static de.eshg.testhelper.ConditionalOnTestHelperEnabled.TEST_HELPER_PROFILE_NAME; import de.eshg.base.PostgresContainerConstants; import de.eshg.base.TestContainersUtil; @@ -39,7 +40,7 @@ public class ServiceDirectoryTestContainerUtil { .withNetwork(network) .withExposedPorts(SD_PORT) .dependsOn(dbContainer) - .withEnv("spring.profiles.active", "test-helper") + .withEnv("spring.profiles.active", TEST_HELPER_PROFILE_NAME) .withEnv("spring.datasource.url", jdbcUrl) .withEnv("SERVER_PORT", Integer.toString(SD_PORT)) .withCreateContainerCmdModifier( diff --git a/backend/lib-service-directory-api/gradle.lockfile b/backend/lib-service-directory-api/gradle.lockfile index e404f567332f989bbdd3918da8207780910c0658..568a2207736367da0035aef18855bbb5d1542fa4 100644 --- a/backend/lib-service-directory-api/gradle.lockfile +++ b/backend/lib-service-directory-api/gradle.lockfile @@ -1,21 +1,22 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -53,24 +54,24 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-statistics-api/gradle.lockfile b/backend/lib-statistics-api/gradle.lockfile index 06dbb2ff09463c86d7b0f212437a6699ede95eaf..8017562d7c3154dd506763857adba48e3e63daef 100644 --- a/backend/lib-statistics-api/gradle.lockfile +++ b/backend/lib-statistics-api/gradle.lockfile @@ -1,15 +1,15 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -46,21 +46,21 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/lib-statistics/gradle.lockfile b/backend/lib-statistics/gradle.lockfile index 056f04b026170e2113153f4301abba02ced7c4bc..7409f4daf861268c37ac393a452d7b9b40481131 100644 --- a/backend/lib-statistics/gradle.lockfile +++ b/backend/lib-statistics/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.adobe.xmp:xmpcore:6.1.11=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.drewnoakes:metadata-extractor:2.19.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -25,8 +25,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -43,9 +44,9 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath commons-logging:commons-logging:1.3.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -53,11 +54,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -65,14 +66,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -105,10 +105,10 @@ org.apache.tika:tika-bom:2.9.2=productionRuntimeClasspath,runtimeClasspath,testR org.apache.tika:tika-core:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-pdf-module:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-xmp-commons:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -127,8 +127,8 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -155,7 +155,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -163,30 +163,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -196,19 +196,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath diff --git a/backend/local-service-directory/gradle.lockfile b/backend/local-service-directory/gradle.lockfile index 08ccc5268ccbc97a8cdabae305deb61ca30bf9d4..9567977f9c9dfdd1552075c905d1b1f07b9e724b 100644 --- a/backend/local-service-directory/gradle.lockfile +++ b/backend/local-service-directory/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.apicatalog:titanium-json-ld:1.3.3=compileClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -31,8 +31,9 @@ com.github.ua-parser:uap-java:1.5.4=compileClasspath com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.zxing:core:3.4.0=compileClasspath com.google.zxing:javase:3.4.0=compileClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath @@ -58,17 +59,17 @@ com.webauthn4j:webauthn4j-util:0.21.5.RELEASE=compileClasspath commons-codec:commons-codec:1.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.11.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-logging:commons-logging:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath io.github.java-diff-utils:java-diff-utils:4.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -78,15 +79,14 @@ io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath, io.setl:rdf-urdna:1.1=compileClasspath io.smallrye.common:smallrye-common-annotation:2.2.0=compileClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.mail:jakarta.mail-api:2.1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.ws.rs:jakarta.ws.rs-api:3.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -116,10 +116,10 @@ org.apache.james:apache-mime4j-dom:0.8.9=compileClasspath,productionRuntimeClass org.apache.james:apache-mime4j-storage:0.8.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath @@ -141,7 +141,7 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -165,14 +165,14 @@ org.junit.platform:junit-platform-commons:1.10.3=testCompileClasspath,testRuntim org.junit.platform:junit-platform-engine:1.10.3=testRuntimeClasspath org.junit.platform:junit-platform-launcher:1.10.3=testRuntimeClasspath org.junit:junit-bom:5.10.3=testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-admin-client:25.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-common:25.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-core:25.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-model-storage-private:25.0.4=compileClasspath -org.keycloak:keycloak-model-storage:25.0.4=compileClasspath -org.keycloak:keycloak-server-spi-private:25.0.4=compileClasspath -org.keycloak:keycloak-server-spi:25.0.4=compileClasspath -org.keycloak:keycloak-services:25.0.4=compileClasspath +org.keycloak:keycloak-admin-client:25.0.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.keycloak:keycloak-common:25.0.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.keycloak:keycloak-core:25.0.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.keycloak:keycloak-model-storage-private:25.0.6=compileClasspath +org.keycloak:keycloak-model-storage:25.0.6=compileClasspath +org.keycloak:keycloak-server-spi-private:25.0.6=compileClasspath +org.keycloak:keycloak-server-spi:25.0.6=compileClasspath +org.keycloak:keycloak-services:25.0.6=compileClasspath org.latencyutils:LatencyUtils:2.0.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.mockito:mockito-core:5.11.0=testCompileClasspath,testRuntimeClasspath org.mockito:mockito-junit-jupiter:5.11.0=testCompileClasspath,testRuntimeClasspath @@ -182,7 +182,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.reactivestreams:reactive-streams:1.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath @@ -191,26 +191,26 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.retry:spring-retry:2.0.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.retry:spring-retry:2.0.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -219,16 +219,16 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/measles-protection/gradle.lockfile b/backend/measles-protection/gradle.lockfile index 8dde70cb09a0977da500a30a3b6a64a898fb19dd..49e9d34706bd7bf14129e3ffb1613c278a779658 100644 --- a/backend/measles-protection/gradle.lockfile +++ b/backend/measles-protection/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.adobe.xmp:xmpcore:6.1.11=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.drewnoakes:metadata-extractor:2.19.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -26,8 +26,9 @@ com.github.virtuald:curvesapi:1.08=compileClasspath,productionRuntimeClasspath,r com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -48,7 +49,7 @@ com.zaxxer:SparseBitSet:1.3=compileClasspath,productionRuntimeClasspath,runtimeC commons-codec:commons-codec:1.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-logging:commons-logging:1.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -61,11 +62,11 @@ io.github.openhtmltopdf:openhtmltopdf-core:1.1.22=productionRuntimeClasspath,run io.github.openhtmltopdf:openhtmltopdf-pdfbox:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-slf4j:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-svg-support:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -73,14 +74,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -119,10 +119,10 @@ org.apache.tika:tika-bom:2.9.2=productionRuntimeClasspath,runtimeClasspath,testR org.apache.tika:tika-core:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-pdf-module:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-xmp-commons:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlbeans:xmlbeans:5.2.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-anim:1.17=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-awt-util:1.17=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -162,9 +162,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -191,7 +191,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -199,30 +199,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -232,19 +232,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/measles-protection/openApi.yaml b/backend/measles-protection/openApi.yaml index fc6b5c8496fc59aa3e53cf82f20e699d5e3e7472..4395cae4decdde9c5a5174bd3af6d223f8c22162 100644 --- a/backend/measles-protection/openApi.yaml +++ b/backend/measles-protection/openApi.yaml @@ -758,6 +758,34 @@ paths: summary: Update status of inbox procedure tags: - InboxProcedure + /organisations/documents/privacy-notice: + get: + operationId: getPrivacyNotice + responses: + "200": + content: + '*/*': + schema: + type: string + format: binary + description: OK + summary: Get the privacy-notice document. + tags: + - OrganisationPortal + /organisations/documents/privacy-policy: + get: + operationId: getPrivacyPolicy + responses: + "200": + content: + '*/*': + schema: + type: string + format: binary + description: OK + summary: Get the privacy-policy document. + tags: + - OrganisationPortal /organisations/report: post: operationId: report @@ -3016,8 +3044,12 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 required: - assignee + - taskVersion BookAppointmentRequest: type: object properties: @@ -4289,7 +4321,7 @@ components: - totalPages GetArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - PROCEDURE_TYPE @@ -4610,7 +4642,7 @@ components: - totalPages GetRelevantArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - EXPORTED_AT @@ -5697,6 +5729,11 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 + required: + - taskVersion SortDirection: type: string enum: @@ -5774,6 +5811,9 @@ components: $ref: "#/components/schemas/TaskStatus" taskType: $ref: "#/components/schemas/TaskType" + version: + type: integer + format: int64 required: - businessModule - createdAt @@ -5784,6 +5824,7 @@ components: - taskId - taskStatus - taskType + - version TaskMetric: type: object properties: diff --git a/backend/measles-protection/src/main/java/de/eshg/measlesprotection/OrganisationPortalController.java b/backend/measles-protection/src/main/java/de/eshg/measlesprotection/OrganisationPortalController.java index c939957ec3c994d97e5657860b15fd1c026f912e..ce18073de652d838af6bfa7324fea695925b2a45 100644 --- a/backend/measles-protection/src/main/java/de/eshg/measlesprotection/OrganisationPortalController.java +++ b/backend/measles-protection/src/main/java/de/eshg/measlesprotection/OrganisationPortalController.java @@ -10,6 +10,12 @@ import de.eshg.rest.service.security.config.BaseUrls; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.http.ContentDisposition; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; @RestController @@ -19,9 +25,16 @@ public class OrganisationPortalController { public static final String BASE_URL = BaseUrls.MeaslesProtection.ORGANISATION_CONTROLLER; private final OrganisationPortalService publicMeaslesProtectionService; + private final Resource privacyNotice; + private final Resource privacyPolicy; - public OrganisationPortalController(OrganisationPortalService publicMeaslesProtectionService) { + public OrganisationPortalController( + OrganisationPortalService publicMeaslesProtectionService, + @Value("classpath:templates/documents/privacy_notice.pdf") Resource privacyNotice, + @Value("classpath:templates/documents/privacy_policy.pdf") Resource privacyPolicy) { this.publicMeaslesProtectionService = publicMeaslesProtectionService; + this.privacyNotice = privacyNotice; + this.privacyPolicy = privacyPolicy; } @PostMapping("/report") @@ -31,4 +44,35 @@ public class OrganisationPortalController { public void report(@RequestBody @Valid ReportCaseRequest request) { publicMeaslesProtectionService.reportCases(request); } + + @GetMapping(path = "/documents/privacy-notice") + @Operation(summary = "Get the privacy-notice document.") + @Transactional(readOnly = true) + public ResponseEntity<Resource> getPrivacyNotice() { + return getPrivacyDocument(privacyNotice); + } + + @GetMapping(path = "/documents/privacy-policy") + @Operation(summary = "Get the privacy-policy document.") + @Transactional(readOnly = true) + public ResponseEntity<Resource> getPrivacyPolicy() { + return getPrivacyDocument(privacyPolicy); + } + + private static ResponseEntity<Resource> getPrivacyDocument(Resource privacyDocument) { + return ResponseEntity.ok() + .header( + HttpHeaders.CONTENT_DISPOSITION, + fileAttachment(privacyDocument.getFilename()).toString()) + .header(HttpHeaders.CONTENT_TYPE, "application/pdf") + .body(privacyDocument); + } + + private static ContentDisposition fileAttachment(String filename) { + return file(filename, ContentDisposition.attachment()); + } + + private static ContentDisposition file(String filename, ContentDisposition.Builder builder) { + return builder.name("file").filename(filename).build(); + } } diff --git a/backend/measles-protection/src/main/java/de/eshg/measlesprotection/testhelper/ProtectionProcedureTestHelperController.java b/backend/measles-protection/src/main/java/de/eshg/measlesprotection/testhelper/ProtectionProcedureTestHelperController.java index 57155b3ff8c927f108f033e0130965a5500527b8..3a4fd9cc5b0950101d6e1bea2045ab1fc2f84fd5 100644 --- a/backend/measles-protection/src/main/java/de/eshg/measlesprotection/testhelper/ProtectionProcedureTestHelperController.java +++ b/backend/measles-protection/src/main/java/de/eshg/measlesprotection/testhelper/ProtectionProcedureTestHelperController.java @@ -5,7 +5,7 @@ package de.eshg.measlesprotection.testhelper; -import de.eshg.auditlog.AuditLogTestHelperApi; +import de.eshg.auditlog.SharedAuditLogTestHelperApi; import de.eshg.lib.auditlog.AuditLogTestHelperService; import de.eshg.measlesprotection.api.MeaslesProtectionProcedurePopulationResult; import de.eshg.measlesprotection.api.draft.OpenProcedureResponse; @@ -25,7 +25,7 @@ import org.springframework.web.service.annotation.PostExchange; @RestController @ConditionalOnTestHelperEnabled public class ProtectionProcedureTestHelperController extends TestHelperController - implements AuditLogTestHelperApi { + implements SharedAuditLogTestHelperApi { private final ProtectionProcedurePopulator populator; private final AuditLogTestHelperService auditLogTestHelperService; diff --git a/backend/measles-protection/src/main/resources/templates/documents/privacy_notice.pdf b/backend/measles-protection/src/main/resources/templates/documents/privacy_notice.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ab8af607ca15d1dad1c5f0d86c282573cca46ac7 Binary files /dev/null and b/backend/measles-protection/src/main/resources/templates/documents/privacy_notice.pdf differ diff --git a/backend/measles-protection/src/main/resources/templates/documents/privacy_policy.pdf b/backend/measles-protection/src/main/resources/templates/documents/privacy_policy.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b102d85d0cd0fb89059e88b7e44b9a370493f4a4 Binary files /dev/null and b/backend/measles-protection/src/main/resources/templates/documents/privacy_policy.pdf differ diff --git a/backend/opendata/gradle.lockfile b/backend/opendata/gradle.lockfile index a6caa68af21c45efcebcaf5016d14d65cb95bbe8..66359487bcd756a33869a133efa2931c88963ca7 100644 --- a/backend/opendata/gradle.lockfile +++ b/backend/opendata/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -37,8 +38,8 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -46,11 +47,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -58,14 +59,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -89,10 +89,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -109,8 +109,8 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -136,7 +136,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -144,29 +144,29 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -175,19 +175,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath diff --git a/backend/relay-server/gradle.lockfile b/backend/relay-server/gradle.lockfile index b570f853f503f833c2065e1e47009c5d5d202d42..1151b581e809524308b4fae28771df82b3983080 100644 --- a/backend/relay-server/gradle.lockfile +++ b/backend/relay-server/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -19,8 +19,9 @@ com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.9.2=testRuntimeC com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.sun.istack:istack-commons-runtime:4.1.2=testRuntimeClasspath @@ -30,42 +31,41 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-buffer:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec-dns:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec-http2:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec-http:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec-socks:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-common:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-handler-proxy:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-handler:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-resolver-dns-classes-macos:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-resolver-dns-native-macos:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-resolver-dns:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-resolver:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-transport-classes-epoll:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-transport-native-epoll:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-transport-native-unix-common:4.1.112.Final=testCompileClasspath,testRuntimeClasspath -io.netty:netty-transport:4.1.112.Final=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-buffer:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-dns:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-http2:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-http:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-socks:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-common:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-handler-proxy:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-handler:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver-dns-classes-macos:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver-dns-native-macos:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver-dns:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport-classes-epoll:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport-native-epoll:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport-native-unix-common:4.1.113.Final=testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport:4.1.113.Final=testCompileClasspath,testRuntimeClasspath io.projectreactor.netty:reactor-netty-core:1.1.22=testCompileClasspath,testRuntimeClasspath io.projectreactor.netty:reactor-netty-http:1.1.22=testCompileClasspath,testRuntimeClasspath -io.projectreactor:reactor-core:3.6.9=testCompileClasspath,testRuntimeClasspath +io.projectreactor:reactor-core:3.6.10=testCompileClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testRuntimeClasspath @@ -82,9 +82,10 @@ org.apache.commons:commons-compress:1.24.0=testCompileClasspath,testRuntimeClass org.apache.commons:commons-lang3:3.14.0=testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath @@ -100,7 +101,7 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt @@ -123,41 +124,41 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.reactivestreams:reactive-streams:1.0.4=testCompileClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-websocket:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-websocket:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-messaging:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-websocket:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-messaging:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-websocket:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/rest-client-commons/build.gradle b/backend/rest-client-commons/build.gradle index b759a0a62bc62c4f1addb3024b6b5822958dd6bc..897b1bf2ef87cf0da673d7fcfa824a0c9eff24f2 100644 --- a/backend/rest-client-commons/build.gradle +++ b/backend/rest-client-commons/build.gradle @@ -8,10 +8,7 @@ dependencies { implementation 'org.springframework.security:spring-security-oauth2-jose' implementation 'org.springframework.security:spring-security-oauth2-resource-server' implementation 'org.apache.httpcomponents.client5:httpclient5' - implementation "org.zalando:logbook-api:latest.release" implementation "org.zalando:logbook-httpclient5:latest.release" - implementation "jakarta.servlet:jakarta.servlet-api" - implementation 'com.fasterxml.jackson.core:jackson-databind' implementation project(":api-commons") runtimeOnly "org.zalando:logbook-spring-boot-starter:latest.release" diff --git a/backend/rest-client-commons/gradle.lockfile b/backend/rest-client-commons/gradle.lockfile index 4daf92a5a340d69fca90e5f8860881ac6a7b37b1..02d53dbbaab69bc29da06acb25359f1ede1025e9 100644 --- a/backend/rest-client-commons/gradle.lockfile +++ b/backend/rest-client-commons/gradle.lockfile @@ -1,11 +1,11 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-core:2.17.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-databind:2.17.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.17.2=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.module:jackson-module-parameter-names:2.17.2=testCompileClasspath,testRuntimeClasspath @@ -19,13 +19,12 @@ com.squareup.okhttp3:okhttp:4.12.0=testCompileClasspath,testRuntimeClasspath com.squareup.okio:okio-jvm:3.6.0=testCompileClasspath,testRuntimeClasspath com.squareup.okio:okio:3.6.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.quarkus:quarkus-junit4-mock:3.14.4=testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.quarkus:quarkus-junit4-mock:3.15.0=testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testRuntimeClasspath net.bytebuddy:byte-buddy-agent:1.14.19=testCompileClasspath,testRuntimeClasspath @@ -37,9 +36,9 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=compileClasspath,productionRu org.apache.httpcomponents.core5:httpcore5:5.2.5=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=testCompileClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath @@ -71,31 +70,31 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath org.zalando:faux-pas:0.9.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath diff --git a/backend/rest-client-commons/src/main/java/de/eshg/rest/client/RequestResponseLoggingRestClientCustomizer.java b/backend/rest-client-commons/src/main/java/de/eshg/rest/client/RequestResponseLoggingRestClientCustomizer.java index 7da1657544046488fe0cdbc85be64e59a63c74b9..a35aebf76d53af2b3dce2fd0ca219b98bccd9179 100644 --- a/backend/rest-client-commons/src/main/java/de/eshg/rest/client/RequestResponseLoggingRestClientCustomizer.java +++ b/backend/rest-client-commons/src/main/java/de/eshg/rest/client/RequestResponseLoggingRestClientCustomizer.java @@ -10,7 +10,6 @@ import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.client.RestClientCustomizer; -import org.springframework.context.annotation.PropertySource; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestClient; import org.zalando.logbook.Logbook; @@ -19,10 +18,9 @@ import org.zalando.logbook.httpclient5.LogbookHttpResponseInterceptor; @AutoConfiguration @ConditionalOnProperty( - name = "de.eshg.rest.client.request-response-logging-enabled", + name = "de.eshg.rest.client.logging-enabled", havingValue = "true", matchIfMissing = true) -@PropertySource("classpath:/common-logbook-client.properties") public class RequestResponseLoggingRestClientCustomizer implements RestClientCustomizer { private final Logbook logbook; diff --git a/backend/rest-client-commons/src/main/resources/common-logbook-client.properties b/backend/rest-client-commons/src/main/resources/common-logbook-client.properties deleted file mode 100644 index e419d6748e430177f84dc6d27bf251fbd3aaa4a9..0000000000000000000000000000000000000000 --- a/backend/rest-client-commons/src/main/resources/common-logbook-client.properties +++ /dev/null @@ -1,4 +0,0 @@ -logbook.format.style=http - -logbook.predicate.exclude[0].path=/actuator/health -logbook.predicate.exclude[1].path=/actuator/prometheus diff --git a/backend/rest-oauth-client-commons/gradle.lockfile b/backend/rest-oauth-client-commons/gradle.lockfile index 7cb9c96b4143c5fe9f8c9eb82fe3ea6ed8e559e8..5be36ff39128659903202d296d106e314b3c7b8e 100644 --- a/backend/rest-oauth-client-commons/gradle.lockfile +++ b/backend/rest-oauth-client-commons/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.nimbusds:content-type:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -10,9 +10,9 @@ com.nimbusds:lang-tag:1.7=compileClasspath,productionRuntimeClasspath,runtimeCla com.nimbusds:nimbus-jose-jwt:9.37.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.nimbusds:oauth2-oidc-sdk:9.43.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testRuntimeClasspath @@ -48,15 +48,15 @@ org.ow2.asm:asm:9.6=compileClasspath,jacocoAnt,productionRuntimeClasspath,runtim org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -65,14 +65,14 @@ org.springframework.security:spring-security-oauth2-core:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/rest-service-commons/build.gradle b/backend/rest-service-commons/build.gradle index 9c95ca6e5b467d7c0222726b0bd8552f08a9bbda..7f0aed937ba0ec96b2b5507d1b8827d38b7681da 100644 --- a/backend/rest-service-commons/build.gradle +++ b/backend/rest-service-commons/build.gradle @@ -1,24 +1,17 @@ plugins { id "eshg.java-lib" - id "java-test-fixtures" } dependencies { - implementation project(':api-commons') - implementation "org.springframework:spring-web" - implementation "org.springframework:spring-webmvc" - implementation "org.springframework:spring-context" - implementation "org.springframework.boot:spring-boot-autoconfigure" - implementation "com.fasterxml.jackson.core:jackson-databind" - implementation "jakarta.servlet:jakarta.servlet-api" - implementation "org.zalando:logbook-api:latest.release" - runtimeOnly "org.zalando:logbook-spring-boot-starter:latest.release" + implementation 'org.slf4j:slf4j-api' + implementation 'org.springframework.boot:spring-boot-autoconfigure' + implementation 'org.springframework.boot:spring-boot-actuator-autoconfigure' + implementation 'org.springframework:spring-web' + implementation 'org.apache.tomcat.embed:tomcat-embed-core' + + implementation project(':test-helper-commons-spring') - testFixturesImplementation project(":test-commons") - testFixturesImplementation "org.zalando:logbook-api:latest.release" - testFixturesImplementation "ch.qos.logback:logback-classic" + compileOnly 'org.jetbrains:annotations:latest.release' - testImplementation project(':test-commons') - testImplementation "org.springframework.boot:spring-boot-starter-web" - testImplementation 'org.springframework.boot:spring-boot-starter-security' + runtimeOnly "org.zalando:logbook-spring-boot-starter:latest.release" } diff --git a/backend/rest-service-commons/gradle.lockfile b/backend/rest-service-commons/gradle.lockfile index f159274cbcec1029c23131a4b96b978d8ca9ecac..6205b19d316fddff9e8f52eaa363cc0a70311780 100644 --- a/backend/rest-service-commons/gradle.lockfile +++ b/backend/rest-service-commons/gradle.lockfile @@ -1,144 +1,82 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.17.2=testCompileClasspath,testRuntimeClasspath -com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2=testCompileClasspath,testRuntimeClasspath -com.fasterxml.jackson.module:jackson-module-parameter-names:2.17.2=testCompileClasspath,testRuntimeClasspath -com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.fasterxml:classmate:1.7.0=testFixturesRuntimeClasspath,testRuntimeClasspath -com.github.docker-java:docker-java-api:3.3.6=testFixturesRuntimeClasspath,testRuntimeClasspath -com.github.docker-java:docker-java-transport-zerodep:3.3.6=testFixturesRuntimeClasspath,testRuntimeClasspath -com.github.docker-java:docker-java-transport:3.3.6=testFixturesRuntimeClasspath,testRuntimeClasspath -com.github.gavlyukovskiy:datasource-decorator-spring-boot-autoconfigure:1.9.2=testFixturesRuntimeClasspath,testRuntimeClasspath -com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.9.2=testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.code.findbugs:jsr305:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.28.0=testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.guava:failureaccess:1.0.2=testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=testFixturesRuntimeClasspath,testRuntimeClasspath -com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=testFixturesRuntimeClasspath,testRuntimeClasspath -com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -com.sun.istack:istack-commons-runtime:4.1.2=testFixturesRuntimeClasspath,testRuntimeClasspath -com.tngtech.archunit:archunit-junit5-api:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath -com.tngtech.archunit:archunit-junit5-engine-api:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath -com.tngtech.archunit:archunit-junit5-engine:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath -com.tngtech.archunit:archunit-junit5:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath -com.tngtech.archunit:archunit:1.3.0=testFixturesRuntimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-annotations:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-core:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-databind:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.fasterxml.jackson:jackson-bom:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:postgres-snapshot-util:1.1=testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:test-utils:1.1.1=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -io.smallrye:jandex:3.1.2=testFixturesRuntimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath -jakarta.inject:jakarta.inject-api:2.0.1=testFixturesRuntimeClasspath,testRuntimeClasspath -jakarta.persistence:jakarta.persistence-api:3.1.0=testFixturesRuntimeClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -jakarta.transaction:jakarta.transaction-api:2.0.1=testFixturesRuntimeClasspath,testRuntimeClasspath -jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -junit:junit:4.13.2=testFixturesRuntimeClasspath,testRuntimeClasspath +jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testRuntimeClasspath net.bytebuddy:byte-buddy-agent:1.14.19=testCompileClasspath,testRuntimeClasspath -net.bytebuddy:byte-buddy:1.14.19=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -net.java.dev.jna:jna:5.13.0=testFixturesRuntimeClasspath,testRuntimeClasspath +net.bytebuddy:byte-buddy:1.14.19=testCompileClasspath,testRuntimeClasspath net.minidev:accessors-smart:2.5.1=testCompileClasspath,testRuntimeClasspath net.minidev:json-smart:2.5.1=testCompileClasspath,testRuntimeClasspath -net.ttddyy:datasource-proxy:1.10=testFixturesRuntimeClasspath,testRuntimeClasspath -org.antlr:antlr4-runtime:4.13.0=testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.commons:commons-compress:1.24.0=testFixturesRuntimeClasspath,testRuntimeClasspath -org.apache.commons:commons-lang3:3.14.0=testFixturesRuntimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apiguardian:apiguardian-api:1.1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.assertj:assertj-core:3.25.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath -org.bouncycastle:bcpkix-jdk18on:1.78.1=testFixturesRuntimeClasspath,testRuntimeClasspath -org.bouncycastle:bcprov-jdk18on:1.78.1=testFixturesRuntimeClasspath,testRuntimeClasspath -org.bouncycastle:bcutil-jdk18on:1.78.1=testFixturesRuntimeClasspath,testRuntimeClasspath -org.checkerframework:checker-qual:3.43.0=testFixturesRuntimeClasspath,testRuntimeClasspath -org.eclipse.angus:angus-activation:2.0.2=testFixturesRuntimeClasspath,testRuntimeClasspath -org.glassfish.jaxb:jaxb-core:4.0.5=testFixturesRuntimeClasspath,testRuntimeClasspath -org.glassfish.jaxb:jaxb-runtime:4.0.5=testFixturesRuntimeClasspath,testRuntimeClasspath -org.glassfish.jaxb:txw2:4.0.5=testFixturesRuntimeClasspath,testRuntimeClasspath -org.hamcrest:hamcrest-core:2.2=testFixturesRuntimeClasspath,testRuntimeClasspath -org.hamcrest:hamcrest:2.2=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=testFixturesRuntimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=testFixturesRuntimeClasspath,testRuntimeClasspath +org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt org.jacoco:org.jacoco.report:0.8.11=jacocoAnt -org.jboss.logging:jboss-logging:3.5.3.Final=testFixturesRuntimeClasspath,testRuntimeClasspath -org.jetbrains:annotations:24.1.0=testFixturesRuntimeClasspath,testRuntimeClasspath -org.junit.jupiter:junit-jupiter-api:5.10.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.jetbrains:annotations:24.1.0=compileClasspath +org.junit.jupiter:junit-jupiter-api:5.10.3=testCompileClasspath,testRuntimeClasspath org.junit.jupiter:junit-jupiter-engine:5.10.3=testRuntimeClasspath org.junit.jupiter:junit-jupiter-params:5.10.3=testCompileClasspath,testRuntimeClasspath org.junit.jupiter:junit-jupiter:5.10.3=testCompileClasspath,testRuntimeClasspath -org.junit.platform:junit-platform-commons:1.10.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.junit.platform:junit-platform-engine:1.10.3=testFixturesRuntimeClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-commons:1.10.3=testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-engine:1.10.3=testRuntimeClasspath org.junit.platform:junit-platform-launcher:1.10.3=testRuntimeClasspath -org.junit:junit-bom:5.10.3=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.junit:junit-bom:5.10.3=testCompileClasspath,testRuntimeClasspath org.mockito:mockito-core:5.11.0=testCompileClasspath,testRuntimeClasspath org.mockito:mockito-junit-jupiter:5.11.0=testCompileClasspath,testRuntimeClasspath org.objenesis:objenesis:3.3=testRuntimeClasspath -org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath +org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testFixturesRuntimeClasspath,testRuntimeClasspath -org.rnorth.duct-tape:duct-tape:1.0.8=testFixturesRuntimeClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath -org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-dependencies:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework.security:spring-security-config:6.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.security:spring-security-core:6.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.security:spring-security-crypto:6.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.security:spring-security-web:6.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.testcontainers:testcontainers:1.19.8=testFixturesRuntimeClasspath,testRuntimeClasspath +org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath -org.zalando:faux-pas:0.9.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.zalando:logbook-api:3.9.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testFixturesCompileClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.zalando:logbook-common:3.9.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.zalando:logbook-core:3.9.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.zalando:logbook-json:3.9.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.zalando:logbook-servlet:3.9.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.zalando:logbook-spring-boot-autoconfigure:3.9.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.zalando:logbook-spring-boot-starter:3.9.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -org.zalando:logbook-spring:3.9.0=productionRuntimeClasspath,runtimeClasspath,testFixturesRuntimeClasspath,testRuntimeClasspath -empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesAnnotationProcessor +org.zalando:faux-pas:0.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.zalando:logbook-api:3.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.zalando:logbook-common:3.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.zalando:logbook-core:3.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.zalando:logbook-json:3.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.zalando:logbook-servlet:3.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.zalando:logbook-spring-boot-autoconfigure:3.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.zalando:logbook-spring-boot-starter:3.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.zalando:logbook-spring:3.9.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/ActiveRequestCounter.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/ActiveRequestCounter.java new file mode 100644 index 0000000000000000000000000000000000000000..3d8f0b0a16339232ef30ae9d9bdae6ea4b296502 --- /dev/null +++ b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/ActiveRequestCounter.java @@ -0,0 +1,66 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.rest.service.commons.filter; + +import de.eshg.testhelper.ConditionalOnTestHelperEnabled; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; + +@Component +@ConditionalOnTestHelperEnabled +public class ActiveRequestCounter { + + private static final Logger log = LoggerFactory.getLogger(ActiveRequestCounter.class); + + public static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(30); + + private final AtomicLong counter = new AtomicLong(); + private final List<CountDownLatch> latches = new ArrayList<>(); + + public void start() { + counter.incrementAndGet(); + } + + public void finish() { + synchronized (latches) { + long activeRequests = counter.decrementAndGet(); + if (activeRequests == 0) { + if (!latches.isEmpty()) { + log.trace("Last active request finished. Notifying {} latches.", latches.size()); + } + latches.forEach(CountDownLatch::countDown); + latches.clear(); + } + } + } + + public void waitUntilAllActiveRequestsFinished() throws InterruptedException { + waitUntilAllActiveRequestsFinished(DEFAULT_TIMEOUT); + } + + public void waitUntilAllActiveRequestsFinished(Duration timeout) throws InterruptedException { + CountDownLatch latch = new CountDownLatch(1); + synchronized (latches) { + long activeRequests = counter.get(); + if (activeRequests == 0) { + log.trace("No active requests"); + return; + } + log.trace("Waiting for {} active request(s) to finish", activeRequests); + latches.add(latch); + } + boolean success = latch.await(timeout.toNanos(), TimeUnit.NANOSECONDS); + Assert.isTrue(success, "Failed to wait for " + latch); + } +} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/ActiveRequestCounterFilter.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/ActiveRequestCounterFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..b0a305a42f1683a5b9743c30d7e323170d4ce0e1 --- /dev/null +++ b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/ActiveRequestCounterFilter.java @@ -0,0 +1,54 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.rest.service.commons.filter; + +import de.eshg.testhelper.ConditionalOnTestHelperEnabled; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +@Component +@ConditionalOnTestHelperEnabled +@Order(FilterOrder.ACTIVE_REQUEST_COUNTER_FILTER_ORDER) +public class ActiveRequestCounterFilter extends OncePerRequestFilter { + + private static final Logger log = LoggerFactory.getLogger(ActiveRequestCounterFilter.class); + + private final ActiveRequestCounter activeRequestCounter; + + public ActiveRequestCounterFilter(ActiveRequestCounter activeRequestCounter) { + log.warn("Creating {}", getClass().getSimpleName()); + this.activeRequestCounter = activeRequestCounter; + } + + @Override + protected void doFilterInternal( + @NotNull HttpServletRequest request, + @NotNull HttpServletResponse response, + @NotNull FilterChain filterChain) + throws ServletException, IOException { + activeRequestCounter.start(); + log.trace( + "Started active request counter for {} {}", request.getMethod(), request.getRequestURI()); + try { + filterChain.doFilter(request, response); + } finally { + log.trace( + "Finishing active request counter for {} {}", + request.getMethod(), + request.getRequestURI()); + activeRequestCounter.finish(); + } + } +} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/FilterOrder.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/FilterOrder.java new file mode 100644 index 0000000000000000000000000000000000000000..a4a02fd5201ace3911b1ec8c7d2cf8ebe3594f8d --- /dev/null +++ b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/FilterOrder.java @@ -0,0 +1,15 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.rest.service.commons.filter; + +import org.springframework.core.Ordered; + +public interface FilterOrder { + + int ACTIVE_REQUEST_COUNTER_FILTER_ORDER = Ordered.HIGHEST_PRECEDENCE; + // make sure to run _before_ the Spring Security filters + int REQUEST_LOGGING_FILTER_ORDER = ACTIVE_REQUEST_COUNTER_FILTER_ORDER + 1; +} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/RequestLoggingAutoConfiguration.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/RequestLoggingAutoConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..3ea73699a1c35314dd18a8b7ce4ff8c1f7d63439 --- /dev/null +++ b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/RequestLoggingAutoConfiguration.java @@ -0,0 +1,15 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.rest.service.commons.filter; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.PropertySource; + +@AutoConfiguration +@PropertySource("classpath:/common-logbook.properties") +@Import({RequestLoggingFilter.class, ActiveRequestCounter.class, ActiveRequestCounterFilter.class}) +public class RequestLoggingAutoConfiguration {} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/RequestLoggingFilter.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/RequestLoggingFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..0daa231772800d60f78b5780688a609595aef4f1 --- /dev/null +++ b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/filter/RequestLoggingFilter.java @@ -0,0 +1,90 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.rest.service.commons.filter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Objects; +import java.util.stream.Collectors; +import org.jetbrains.annotations.VisibleForTesting; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +/** + * This filter logs essential information about incoming HTTP requests to the regular log file, + * supplementing the detailed logging provided by Logbook (configured for debug-level in + * production). + * + * <p>It logs the HTTP method, URI, and response status of requests to help trace request processing + * without needing extensive debug logs. + * + * <p>The filter is configured with the highest precedence to ensure it logs requests before Spring + * Security filters. + */ +@Component +@Order(FilterOrder.REQUEST_LOGGING_FILTER_ORDER) +public class RequestLoggingFilter extends OncePerRequestFilter { + + private static final Logger log = LoggerFactory.getLogger(RequestLoggingFilter.class); + + private final String actuatorBasePath; + + public RequestLoggingFilter(WebEndpointProperties webEndpointProperties) { + this.actuatorBasePath = webEndpointProperties.getBasePath(); + } + + @Override + protected void doFilterInternal( + HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + if (request.getRequestURI().startsWith(actuatorBasePath + "/")) { + // Do not log calls to the actuator endpoint + filterChain.doFilter(request, response); + return; + } + log.info( + "Starting to process {} {}{}", + request.getMethod(), + request.getRequestURI(), + maskedQueryString(request.getQueryString())); + try { + filterChain.doFilter(request, response); + } finally { + log.info( + "Processed {} {} with result {}", + request.getMethod(), + request.getRequestURI(), + HttpStatus.valueOf(response.getStatus())); + } + } + + @VisibleForTesting + static String maskedQueryString(String queryString) { + if (queryString == null || queryString.isBlank()) { + return ""; + } + UriComponents uriComponents = UriComponentsBuilder.newInstance().query(queryString).build(); + return uriComponents.getQueryParams().entrySet().stream() + .map( + entry -> { + if (entry.getValue().stream().allMatch(Objects::isNull)) { + return entry.getKey(); + } + return "%s=[MASKED]".formatted(entry.getKey()); + }) + .collect(Collectors.joining("&", "?", "")); + } +} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/FilteredBodyServletHttpRequest.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/FilteredBodyServletHttpRequest.java deleted file mode 100644 index f872bbb2cecc62c73aeb02e3893d58d988d3faee..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/FilteredBodyServletHttpRequest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging; - -import de.eshg.rest.service.commons.logging.filter.MaskingRequestFilter; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletRequestWrapper; -import java.io.IOException; -import java.util.Optional; -import org.springframework.core.annotation.AnnotatedMethod; -import org.zalando.logbook.HttpHeaders; -import org.zalando.logbook.HttpRequest; -import org.zalando.logbook.Origin; - -public class FilteredBodyServletHttpRequest extends HttpServletRequestWrapper - implements HttpRequest { - - private final Object body; - private final AnnotatedMethod annotatedMethod; - private final MaskingRequestFilter maskingRequestFilter; - private final HttpServletRequest request; - private boolean withBody = false; - - public FilteredBodyServletHttpRequest( - HttpServletRequest request, - Object body, - AnnotatedMethod annotatedMethod, - MaskingRequestFilter maskingRequestFilter) { - super(request); - this.request = request; - this.body = body; - this.annotatedMethod = annotatedMethod; - this.maskingRequestFilter = maskingRequestFilter; - } - - @Override - public String getRemote() { - return getRemoteAddr(); - } - - @Override - public String getMethod() { - return super.getMethod(); - } - - @Override - public String getScheme() { - return super.getScheme(); - } - - @Override - public String getHost() { - return getServerName(); - } - - @Override - public Optional<Integer> getPort() { - return Optional.of(getServerPort()); - } - - @Override - public String getPath() { - return getRequestURI(); - } - - @Override - public String getQuery() { - return Optional.ofNullable(getParameterMap()) - .map(parameters -> maskingRequestFilter.filterQuery(parameters, annotatedMethod)) - .orElse(""); - } - - @Override - public HttpRequest withBody() { - this.withBody = true; - return this; - } - - @Override - public HttpRequest withoutBody() { - this.withBody = false; - return this; - } - - @Override - public Origin getOrigin() { - return Origin.REMOTE; - } - - @Override - public HttpHeaders getHeaders() { - return maskingRequestFilter.filterRequestHeader(this.request); - } - - @Override - public byte[] getBody() throws IOException { - if (!withBody || body == null) { - return new byte[0]; - } - - return maskingRequestFilter.filterRequestBody(body).getBytes(getCharset()); - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/FilteredBodyServletHttpResponse.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/FilteredBodyServletHttpResponse.java deleted file mode 100644 index bb8eb03ee26cebfac4bf82cb768cb9692cb765ac..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/FilteredBodyServletHttpResponse.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging; - -import de.eshg.rest.service.commons.logging.filter.MaskingResponseFilter; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.servlet.http.HttpServletResponseWrapper; -import java.io.IOException; -import org.zalando.logbook.HttpHeaders; -import org.zalando.logbook.HttpResponse; -import org.zalando.logbook.Origin; - -public class FilteredBodyServletHttpResponse extends HttpServletResponseWrapper - implements HttpResponse { - - private final Object body; - private final String protocol; - private final MaskingResponseFilter maskingResponseFilter; - private final HttpServletResponse response; - private boolean withBody; - - public FilteredBodyServletHttpResponse( - HttpServletResponse response, - Object body, - String protocol, - MaskingResponseFilter maskingResponseFilter) { - super(response); - this.response = response; - this.body = body; - this.protocol = protocol; - this.maskingResponseFilter = maskingResponseFilter; - } - - @Override - public int getStatus() { - return super.getStatus(); - } - - @Override - public HttpResponse withBody() { - this.withBody = true; - return this; - } - - @Override - public HttpResponse withoutBody() { - this.withBody = false; - return this; - } - - @Override - public Origin getOrigin() { - return Origin.LOCAL; - } - - @Override - public HttpHeaders getHeaders() { - return maskingResponseFilter.filterResponseHeaders(response); - } - - @Override - public byte[] getBody() throws IOException { - if (!withBody || this.body == null) { - return new byte[0]; - } - - return maskingResponseFilter.filterResponseBody(body).getBytes(getCharset()); - } - - @Override - public String getProtocolVersion() { - return protocol; - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/FilteringLogbookAdapter.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/FilteringLogbookAdapter.java deleted file mode 100644 index e7c397c230fae07a7cf57e1b1d85c659f94f6ba9..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/FilteringLogbookAdapter.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging; - -import de.eshg.rest.service.commons.logging.filter.MaskingRequestFilter; -import de.eshg.rest.service.commons.logging.filter.MaskingResponseFilter; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Optional; -import java.util.UUID; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.MethodParameter; -import org.springframework.core.annotation.AnnotatedMethod; -import org.springframework.stereotype.Component; -import org.zalando.logbook.Logbook; -import org.zalando.logbook.Logbook.ResponseProcessingStage; -import org.zalando.logbook.Logbook.ResponseWritingStage; - -@Component -public class FilteringLogbookAdapter { - - private final String responseWritingStageName = - FilteringLogbookAdapter.class.getName() + "-WRITING" + UUID.randomUUID(); - private final String responseProcessingStageName = - FilteringLogbookAdapter.class.getName() + "-PROCESSING" + UUID.randomUUID(); - - private static final Logger log = LoggerFactory.getLogger(FilteringLogbookAdapter.class); - - private final Logbook logbook; - private final MaskingRequestFilter maskingRequestFilter; - private final MaskingResponseFilter maskingResponseFilter; - - public FilteringLogbookAdapter( - Logbook logbook, - MaskingRequestFilter maskingRequestFilter, - MaskingResponseFilter maskingResponseFilter) { - this.logbook = logbook; - this.maskingRequestFilter = maskingRequestFilter; - this.maskingResponseFilter = maskingResponseFilter; - } - - public void handleRequest(HttpServletRequest request, AnnotatedMethod annotatedMethod) { - handleRequest(request, null, annotatedMethod); - } - - public void handleRequest(HttpServletRequest request, MethodParameter parameter) { - handleRequest(request, null, parameter); - } - - public void handleRequest( - HttpServletRequest request, Object body, MethodParameter methodParameter) { - handleRequest(request, body, getParentAnnotatedMethod(methodParameter)); - } - - private void handleRequest( - HttpServletRequest request, Object body, AnnotatedMethod annotatedMethod) { - try { - ResponseProcessingStage responseProcessingStage = - processRequest(request, body, annotatedMethod); - request.setAttribute(responseProcessingStageName, responseProcessingStage); - } catch (Exception e) { - log.warn("Failed to log request", e); - } - } - - public void handleResponse( - HttpServletRequest servletRequest, HttpServletResponse servletResponse, Object body) { - try { - ResponseWritingStage responseWritingStage = - processResponse(servletRequest, servletResponse, body); - servletRequest.setAttribute(responseWritingStageName, responseWritingStage); - } catch (Exception e) { - log.warn("Failed to log response", e); - } - } - - public void handleFinalizedResponse(HttpServletRequest request, HttpServletResponse response) - throws IOException { - ResponseWritingStage responseWritingStage = - (ResponseWritingStage) request.getAttribute(responseWritingStageName); - - if (responseWritingStage == null) { - responseWritingStage = processResponse(request, response, null); - } - - response.flushBuffer(); - responseWritingStage.write(); - } - - private ResponseWritingStage processResponse( - HttpServletRequest servletRequest, HttpServletResponse servletResponse, Object responseBody) - throws IOException { - ResponseProcessingStage responseProcessingStage = - (ResponseProcessingStage) servletRequest.getAttribute(responseProcessingStageName); - - if (responseProcessingStage == null) { - responseProcessingStage = processRequest(servletRequest, null, null); - } - - return responseProcessingStage.process( - new FilteredBodyServletHttpResponse( - servletResponse, responseBody, servletRequest.getProtocol(), maskingResponseFilter)); - } - - private ResponseProcessingStage processRequest( - HttpServletRequest request, Object requestBody, AnnotatedMethod annotatedMethod) - throws IOException { - return logbook - .process( - new FilteredBodyServletHttpRequest( - request, requestBody, annotatedMethod, maskingRequestFilter)) - .write(); - } - - private AnnotatedMethod getParentAnnotatedMethod(MethodParameter methodParameter) { - return Optional.ofNullable(methodParameter.getMethod()).map(AnnotatedMethod::new).orElse(null); - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/LoggingFilter.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/LoggingFilter.java deleted file mode 100644 index 32ac2f3ff101f73edb28f659670e61c880ddf592..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/LoggingFilter.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging; - -import jakarta.servlet.FilterChain; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.web.filter.OncePerRequestFilter; - -/** - * This filter executes the writing of the response log. The writing is deferred to have all - * available headers, added by other filters, to be logged, too. At this point however, we do not - * have access to the deserialized body, thus we must pass it in the {@link - * LoggingResponseBodyAdvice}. - */ -@Order(Ordered.HIGHEST_PRECEDENCE) -public class LoggingFilter extends OncePerRequestFilter { - - private final FilteringLogbookAdapter eshgLogBookAdapter; - - public LoggingFilter(FilteringLogbookAdapter eshgLogBookAdapter) { - this.eshgLogBookAdapter = eshgLogBookAdapter; - } - - @Override - protected void doFilterInternal( - HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - filterChain.doFilter(request, response); - eshgLogBookAdapter.handleFinalizedResponse(request, response); - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/LoggingRequestBodyAdvice.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/LoggingRequestBodyAdvice.java deleted file mode 100644 index 918274039507f00357d66b3e1452d817be87ad40..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/LoggingRequestBodyAdvice.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging; - -import jakarta.servlet.http.HttpServletRequest; -import java.lang.reflect.Type; -import org.springframework.core.MethodParameter; -import org.springframework.http.HttpInputMessage; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter; - -/** - * This controller advice handles request with a body and passes them to logging. This happens at - * the first point in time when the body is available as deserialized java object, which we need - * since we respect the {@link de.eshg.api.commons.CanBeLogged} annotation for masking. - */ -@ControllerAdvice -public class LoggingRequestBodyAdvice extends RequestBodyAdviceAdapter { - - private final HttpServletRequest request; - private final FilteringLogbookAdapter eshgLogbookAdapter; - - public LoggingRequestBodyAdvice( - HttpServletRequest request, FilteringLogbookAdapter eshgLogbookAdapter) { - this.request = request; - this.eshgLogbookAdapter = eshgLogbookAdapter; - } - - @Override - public boolean supports( - MethodParameter methodParameter, - Type targetType, - Class<? extends HttpMessageConverter<?>> converterType) { - return true; - } - - @Override - public Object afterBodyRead( - Object body, - HttpInputMessage inputMessage, - MethodParameter parameter, - Type targetType, - Class<? extends HttpMessageConverter<?>> converterType) { - eshgLogbookAdapter.handleRequest(request, body, parameter); - return super.afterBodyRead(body, inputMessage, parameter, targetType, converterType); - } - - @Override - public Object handleEmptyBody( - Object body, - HttpInputMessage inputMessage, - MethodParameter parameter, - Type targetType, - Class<? extends HttpMessageConverter<?>> converterType) { - eshgLogbookAdapter.handleRequest(request, parameter); - return super.handleEmptyBody(body, inputMessage, parameter, targetType, converterType); - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/LoggingResponseBodyAdvice.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/LoggingResponseBodyAdvice.java deleted file mode 100644 index 046883338f39f279bc133595914bc416e0e7603f..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/LoggingResponseBodyAdvice.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging; - -import org.springframework.core.MethodParameter; -import org.springframework.http.MediaType; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.server.ServerHttpRequest; -import org.springframework.http.server.ServerHttpResponse; -import org.springframework.http.server.ServletServerHttpRequest; -import org.springframework.http.server.ServletServerHttpResponse; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; - -/** - * This controller advice handles responses passes them to logging. This happens at the last point - * in time when the body is available as deserialized java object, which we need since we respect - * the {@link de.eshg.api.commons.CanBeLogged} annotation for masking. - */ -@ControllerAdvice -public class LoggingResponseBodyAdvice implements ResponseBodyAdvice<Object> { - - private final FilteringLogbookAdapter eshgLogbookAdapter; - - public LoggingResponseBodyAdvice(FilteringLogbookAdapter eshgLogbookAdapter) { - this.eshgLogbookAdapter = eshgLogbookAdapter; - } - - @Override - public boolean supports( - MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { - return true; - } - - @Override - public Object beforeBodyWrite( - Object body, - MethodParameter returnType, - MediaType selectedContentType, - Class<? extends HttpMessageConverter<?>> selectedConverterType, - ServerHttpRequest request, - ServerHttpResponse response) { - if (!(request instanceof ServletServerHttpRequest servletServerHttpRequest) - || !(response instanceof ServletServerHttpResponse servletServerHttpResponse)) { - return body; - } - - eshgLogbookAdapter.handleResponse( - servletServerHttpRequest.getServletRequest(), - servletServerHttpResponse.getServletResponse(), - body); - return body; - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/RequestLoggingUtils.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/RequestLoggingUtils.java deleted file mode 100644 index 40678036ad9a38007a12f8b8523cfed0166bb1d4..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/RequestLoggingUtils.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging; - -import de.eshg.api.commons.CanBeLogged; -import de.eshg.rest.service.commons.utils.RequestParameterUtil; -import java.util.Collections; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; -import org.springframework.core.MethodParameter; -import org.springframework.core.annotation.AnnotatedMethod; - -public class RequestLoggingUtils { - - public static Set<String> getNamesOfParametersThatCanBeLogged(AnnotatedMethod handlerMethod) { - if (handlerMethod == null) { - return Collections.emptySet(); - } - - return RequestParameterUtil.getMethodParameters(handlerMethod) - .filter(RequestLoggingUtils::canBeLogged) - .map(RequestParameterUtil::resolveRequestParameterName) - .collect(Collectors.toSet()); - } - - private static boolean canBeLogged(MethodParameter methodParameter) { - boolean isUuidParameter = UUID.class.isAssignableFrom(methodParameter.getParameterType()); - boolean canBeLoggedAnnotationIsPresent = - methodParameter.hasParameterAnnotation(CanBeLogged.class); - - return isUuidParameter || canBeLoggedAnnotationIsPresent; - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/RestServiceLoggingAutoConfiguration.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/RestServiceLoggingAutoConfiguration.java deleted file mode 100644 index 4d20857bce31d6b1ad36c9d3d6da96a342d18955..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/RestServiceLoggingAutoConfiguration.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging; - -import de.eshg.rest.service.commons.logging.error.ProblemDetailMixin; -import de.eshg.rest.service.commons.logging.filter.MaskingRequestFilter; -import de.eshg.rest.service.commons.logging.filter.MaskingResponseFilter; -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.PropertySource; -import org.springframework.http.ProblemDetail; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -@AutoConfiguration -@ConditionalOnProperty(name = "de.eshg.rest.service.masking-enabled", havingValue = "true") -@Import({ - MaskingRequestFilter.class, - MaskingResponseFilter.class, - FilteringLogbookAdapter.class, - WithoutBodyLoggingHandlerInterceptor.class, - LoggingRequestBodyAdvice.class, - LoggingResponseBodyAdvice.class, - LoggingFilter.class -}) -@AutoConfigureAfter(WebMvcAutoConfiguration.class) -@PropertySource("classpath:common-logbook-service.properties") -public class RestServiceLoggingAutoConfiguration { - - @Bean - Jackson2ObjectMapperBuilderCustomizer problemDetailMixinCustomizer() { - return jacksonObjectMapperBuilder -> - jacksonObjectMapperBuilder.mixIn(ProblemDetail.class, ProblemDetailMixin.class); - } - - @Configuration - static class LoggingInterceptorWebMvcConfigurer implements WebMvcConfigurer { - private final WithoutBodyLoggingHandlerInterceptor eshgWithoutBodyLoggingHandlerInterceptor; - - LoggingInterceptorWebMvcConfigurer( - WithoutBodyLoggingHandlerInterceptor eshgWithoutBodyLoggingHandlerInterceptor) { - this.eshgWithoutBodyLoggingHandlerInterceptor = eshgWithoutBodyLoggingHandlerInterceptor; - } - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(eshgWithoutBodyLoggingHandlerInterceptor); - } - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/WithoutBodyLoggingHandlerInterceptor.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/WithoutBodyLoggingHandlerInterceptor.java deleted file mode 100644 index b8327a51952c4f8d248e6330a8d48c53651717e6..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/WithoutBodyLoggingHandlerInterceptor.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.util.Arrays; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.HandlerInterceptor; - -/** - * This interceptor, intercepts request <i>without</i> a body and passes them to be logged. - * - * <p>When we expect a body (i.e. the controller method has a {@link RequestBody}) annotation, this - * request will be handled by {@link LoggingRequestBodyAdvice} again, thus in this case it is not - * passed to be logged. - */ -class WithoutBodyLoggingHandlerInterceptor implements HandlerInterceptor { - - private final FilteringLogbookAdapter eshgLogBookAdapter; - - WithoutBodyLoggingHandlerInterceptor(FilteringLogbookAdapter eshgLogBookAdapter) { - this.eshgLogBookAdapter = eshgLogBookAdapter; - } - - @Override - public boolean preHandle( - HttpServletRequest request, HttpServletResponse response, Object handler) { - if (!(handler instanceof HandlerMethod handlerMethod) || shouldHaveRequestBody(handlerMethod)) { - return true; - } - - eshgLogBookAdapter.handleRequest(request, handlerMethod); - return true; - } - - private boolean shouldHaveRequestBody(HandlerMethod handlerMethod) { - return Arrays.stream(handlerMethod.getMethodParameters()) - .anyMatch(methodParameter -> methodParameter.hasParameterAnnotation(RequestBody.class)); - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/error/ProblemDetailMixin.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/error/ProblemDetailMixin.java deleted file mode 100644 index edc848fb0835b6fea970dff8b4ed5bec517d5f55..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/error/ProblemDetailMixin.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging.error; - -import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY; - -import com.fasterxml.jackson.annotation.JsonInclude; -import de.eshg.api.commons.CanBeLogged; -import java.net.URI; -import java.util.Map; -import org.springframework.http.converter.json.ProblemDetailJacksonMixin; - -@JsonInclude(NON_EMPTY) -public interface ProblemDetailMixin extends ProblemDetailJacksonMixin { - - @CanBeLogged - URI getType(); - - @CanBeLogged - String getTitle(); - - @CanBeLogged - int getStatus(); - - @CanBeLogged - String getDetail(); - - @CanBeLogged - URI getInstance(); - - @Override - @CanBeLogged - Map<String, Object> getProperties(); -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/HeaderFilterUtils.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/HeaderFilterUtils.java deleted file mode 100644 index 18f1a487ddd77fbbb34eeef6fdf422231f829479..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/HeaderFilterUtils.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging.filter; - -import java.util.Set; -import java.util.stream.Collectors; - -class HeaderFilterUtils { - - private HeaderFilterUtils() {} - - public static final Set<String> WELL_KNOWN_HEADERS_THAT_CAN_BE_LOGGED = - Set.of( - org.springframework.http.HttpHeaders.ACCEPT, - org.springframework.http.HttpHeaders.ACCEPT_CHARSET, - org.springframework.http.HttpHeaders.ACCEPT_ENCODING, - org.springframework.http.HttpHeaders.ACCEPT_LANGUAGE, - org.springframework.http.HttpHeaders.ACCEPT_PATCH, - org.springframework.http.HttpHeaders.ACCEPT_RANGES, - org.springframework.http.HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, - org.springframework.http.HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, - org.springframework.http.HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, - org.springframework.http.HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, - org.springframework.http.HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, - org.springframework.http.HttpHeaders.ACCESS_CONTROL_MAX_AGE, - org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, - org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, - org.springframework.http.HttpHeaders.AGE, - org.springframework.http.HttpHeaders.ALLOW, - org.springframework.http.HttpHeaders.CACHE_CONTROL, - org.springframework.http.HttpHeaders.CONNECTION, - org.springframework.http.HttpHeaders.CONTENT_ENCODING, - org.springframework.http.HttpHeaders.CONTENT_DISPOSITION, - org.springframework.http.HttpHeaders.CONTENT_LANGUAGE, - org.springframework.http.HttpHeaders.CONTENT_LENGTH, - org.springframework.http.HttpHeaders.CONTENT_LOCATION, - org.springframework.http.HttpHeaders.CONTENT_RANGE, - org.springframework.http.HttpHeaders.CONTENT_TYPE, - org.springframework.http.HttpHeaders.COOKIE, - org.springframework.http.HttpHeaders.DATE, - org.springframework.http.HttpHeaders.ETAG, - org.springframework.http.HttpHeaders.EXPECT, - org.springframework.http.HttpHeaders.EXPIRES, - org.springframework.http.HttpHeaders.FROM, - org.springframework.http.HttpHeaders.HOST, - org.springframework.http.HttpHeaders.IF_MATCH, - org.springframework.http.HttpHeaders.IF_MODIFIED_SINCE, - org.springframework.http.HttpHeaders.IF_NONE_MATCH, - org.springframework.http.HttpHeaders.IF_RANGE, - org.springframework.http.HttpHeaders.IF_UNMODIFIED_SINCE, - org.springframework.http.HttpHeaders.LAST_MODIFIED, - org.springframework.http.HttpHeaders.LINK, - org.springframework.http.HttpHeaders.LOCATION, - org.springframework.http.HttpHeaders.MAX_FORWARDS, - org.springframework.http.HttpHeaders.ORIGIN, - org.springframework.http.HttpHeaders.PRAGMA, - org.springframework.http.HttpHeaders.PROXY_AUTHENTICATE, - org.springframework.http.HttpHeaders.PROXY_AUTHORIZATION, - org.springframework.http.HttpHeaders.RANGE, - org.springframework.http.HttpHeaders.REFERER, - org.springframework.http.HttpHeaders.RETRY_AFTER, - org.springframework.http.HttpHeaders.SERVER, - org.springframework.http.HttpHeaders.SET_COOKIE, - org.springframework.http.HttpHeaders.SET_COOKIE2, - org.springframework.http.HttpHeaders.TE, - org.springframework.http.HttpHeaders.TRAILER, - org.springframework.http.HttpHeaders.TRANSFER_ENCODING, - org.springframework.http.HttpHeaders.UPGRADE, - org.springframework.http.HttpHeaders.USER_AGENT, - org.springframework.http.HttpHeaders.VARY, - org.springframework.http.HttpHeaders.VIA, - org.springframework.http.HttpHeaders.WARNING, - org.springframework.http.HttpHeaders.WWW_AUTHENTICATE) - .stream() - .map(String::toLowerCase) - .collect(Collectors.toSet()); -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/LoggingDecisionAnnotationIntrospector.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/LoggingDecisionAnnotationIntrospector.java deleted file mode 100644 index 9bdccf6c83d020ff86a66197ad42445c6d32ab05..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/LoggingDecisionAnnotationIntrospector.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging.filter; - -import com.fasterxml.jackson.databind.introspect.Annotated; -import com.fasterxml.jackson.databind.introspect.AnnotatedClass; -import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; -import de.eshg.api.commons.CanBeLogged; -import java.io.Serial; -import java.util.UUID; -import org.springframework.beans.BeanUtils; - -public class LoggingDecisionAnnotationIntrospector extends JacksonAnnotationIntrospector { - - @Serial private static final long serialVersionUID = 1L; - - @Override - public Object findSerializer(Annotated annotated) { - if (shouldBeMasked(annotated)) { - return new MaskingSerializer(); - } - return super.findSerializer(annotated); - } - - private boolean shouldBeMasked(Annotated am) { - if (am instanceof AnnotatedClass) { - return false; - } - - if (!BeanUtils.isSimpleProperty(am.getRawType())) { - return false; - } - - if (isAnnotatedWithCanBeLogged(am)) { - return false; - } - - return !isUuid(am); - } - - private boolean isUuid(Annotated am) { - return UUID.class.isAssignableFrom(am.getRawType()); - } - - private boolean isAnnotatedWithCanBeLogged(Annotated am) { - return _hasAnnotation(am, CanBeLogged.class); - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/MaskingRequestFilter.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/MaskingRequestFilter.java deleted file mode 100644 index 4c879cad55bd5e64fff2b45c90c10350d1625b84..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/MaskingRequestFilter.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging.filter; - -import static de.eshg.rest.service.commons.logging.filter.HeaderFilterUtils.WELL_KNOWN_HEADERS_THAT_CAN_BE_LOGGED; -import static java.util.Collections.list; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import de.eshg.rest.service.commons.logging.RequestLoggingUtils; -import jakarta.servlet.http.HttpServletRequest; -import java.io.UncheckedIOException; -import java.util.AbstractMap.SimpleEntry; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; -import java.util.function.UnaryOperator; -import org.springframework.core.annotation.AnnotatedMethod; -import org.springframework.stereotype.Component; -import org.springframework.web.util.UriComponentsBuilder; -import org.zalando.logbook.HttpHeaders; - -@Component -public class MaskingRequestFilter { - - private final ObjectMapper objectMapper; - - public MaskingRequestFilter(ObjectMapper objectMapper) { - this.objectMapper = - objectMapper.copy().setAnnotationIntrospector(new LoggingDecisionAnnotationIntrospector()); - } - - public String filterRequestBody(Object body) { - try { - return objectMapper.writeValueAsString(body); - } catch (JsonProcessingException e) { - throw new UncheckedIOException(e); - } - } - - public String filterQuery(Map<String, String[]> parameters, AnnotatedMethod handlerMethod) { - Set<String> allowedQueryParameters = - RequestLoggingUtils.getNamesOfParametersThatCanBeLogged(handlerMethod); - - UriComponentsBuilder builder = UriComponentsBuilder.fromPath(""); - parameters.entrySet().stream() - .map(maskUnknownQueryParameters(allowedQueryParameters)) - .forEach( - maskedParameter -> - builder.queryParam( - maskedParameter.getKey(), Arrays.asList(maskedParameter.getValue()))); - - return Optional.ofNullable(builder.build().getQuery()).orElse(""); - } - - private UnaryOperator<Entry<String, String[]>> maskUnknownQueryParameters( - Set<String> allowedQueryParameters) { - return parameter -> { - if (allowedQueryParameters.contains(parameter.getKey())) { - return parameter; - } - - return new SimpleEntry<>(parameter.getKey(), new String[] {MaskingSerializer.MASK}); - }; - } - - public HttpHeaders filterRequestHeader(HttpServletRequest request) { - HttpHeaders headers = HttpHeaders.empty(); - for (String header : list(request.getHeaderNames())) { - headers = headers.update(header, maskHeader(header, request)); - } - return headers; - } - - private List<String> maskHeader(String header, HttpServletRequest request) { - if (WELL_KNOWN_HEADERS_THAT_CAN_BE_LOGGED.contains(header.toLowerCase())) { - return list(request.getHeaders(header)); - } - - return List.of(MaskingSerializer.MASK); - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/MaskingResponseFilter.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/MaskingResponseFilter.java deleted file mode 100644 index 7576a80814172ce6b8b9ccdbbb8011e814ce0e50..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/MaskingResponseFilter.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging.filter; - -import static de.eshg.rest.service.commons.logging.filter.HeaderFilterUtils.WELL_KNOWN_HEADERS_THAT_CAN_BE_LOGGED; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.servlet.http.HttpServletResponse; -import java.io.UncheckedIOException; -import java.util.ArrayList; -import java.util.List; -import org.springframework.stereotype.Component; -import org.zalando.logbook.HttpHeaders; - -@Component -public class MaskingResponseFilter { - private final ObjectMapper objectMapper; - - public MaskingResponseFilter(ObjectMapper objectMapper) { - this.objectMapper = - objectMapper.copy().setAnnotationIntrospector(new LoggingDecisionAnnotationIntrospector()); - } - - public String filterResponseBody(Object body) { - try { - return objectMapper.writeValueAsString(body); - } catch (JsonProcessingException e) { - throw new UncheckedIOException(e); - } - } - - public HttpHeaders filterResponseHeaders(HttpServletResponse response) { - HttpHeaders headers = HttpHeaders.empty(); - for (String header : response.getHeaderNames()) { - headers = headers.update(header, maskHeader(header, response)); - } - return headers; - } - - private List<String> maskHeader(String headerName, HttpServletResponse response) { - if (WELL_KNOWN_HEADERS_THAT_CAN_BE_LOGGED.contains(headerName.toLowerCase())) { - return new ArrayList<>(response.getHeaders(headerName)); - } - - return List.of(MaskingSerializer.MASK); - } -} diff --git a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/MaskingSerializer.java b/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/MaskingSerializer.java deleted file mode 100644 index e6d831493f5c36ce863e85daad9fd145e7c8a2a8..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/main/java/de/eshg/rest/service/commons/logging/filter/MaskingSerializer.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.commons.logging.filter; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import java.io.IOException; - -public class MaskingSerializer extends JsonSerializer<Object> { - - public static final String MASK = "[masked]"; - - @Override - public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { - gen.writeString(MASK); - } -} diff --git a/backend/rest-service-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/backend/rest-service-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 6cf0b5a06c8b0e2d38ca6d346dea3656b507b970..9c00a5b41a5d7e41f6cf2c04c9628b0d8fdcbd42 100644 --- a/backend/rest-service-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/backend/rest-service-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,2 +1,2 @@ de.eshg.rest.service.commons.ClockAutoConfiguration -de.eshg.rest.service.commons.logging.RestServiceLoggingAutoConfiguration +de.eshg.rest.service.commons.filter.RequestLoggingAutoConfiguration diff --git a/backend/rest-service-commons/src/main/resources/common-logbook-service.properties b/backend/rest-service-commons/src/main/resources/common-logbook.properties similarity index 84% rename from backend/rest-service-commons/src/main/resources/common-logbook-service.properties rename to backend/rest-service-commons/src/main/resources/common-logbook.properties index f929c35797a81d5adb8861671f79592c2937aa64..651a5e27fa3047d7780218d2c9e18b555c10e412 100644 --- a/backend/rest-service-commons/src/main/resources/common-logbook-service.properties +++ b/backend/rest-service-commons/src/main/resources/common-logbook.properties @@ -1,8 +1,9 @@ # Note: Unfortunately we cannot set the logging level here (logging.level.org.zalando.logbook=TRACE) # See https://docs.spring.io/spring-boot/docs/3.2.1/reference/html/features.html#features.logging.custom-log-configuration + logbook.format.style=http + +logbook.write.max-body-size=1024 + logbook.predicate.exclude[0].path=/actuator/health logbook.predicate.exclude[1].path=/actuator/prometheus - -logbook.filter.enabled=false -logbook.secure-filter.enabled=false diff --git a/backend/rest-service-commons/src/testFixtures/java/de/eshg/rest/service/common/CapturedRequestLoggingTraits.java b/backend/rest-service-commons/src/testFixtures/java/de/eshg/rest/service/common/CapturedRequestLoggingTraits.java deleted file mode 100644 index 83f6ad7c747e7e1ae14e33c81498872e6a3c5f66..0000000000000000000000000000000000000000 --- a/backend/rest-service-commons/src/testFixtures/java/de/eshg/rest/service/common/CapturedRequestLoggingTraits.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: Apache-2.0 - */ - -package de.eshg.rest.service.common; - -import ch.qos.logback.classic.Level; -import de.cronn.assertions.validationfile.normalization.IdNormalizer; -import de.cronn.assertions.validationfile.normalization.IncrementingIdProvider; -import de.cronn.assertions.validationfile.normalization.SimpleRegexReplacement; -import de.cronn.assertions.validationfile.normalization.ValidationNormalizer; -import de.cronn.commons.lang.Action; -import de.eshg.base.logging.CapturedLoggingTraits; -import de.eshg.base.logging.EventFilter; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import org.zalando.logbook.Logbook; - -public interface CapturedRequestLoggingTraits extends CapturedLoggingTraits { - - @Override - default ValidationNormalizer defaultValidationNormalizer() { - return ValidationNormalizer.combine( - CapturedLoggingTraits.super.defaultValidationNormalizer(), - getDateTimeNormalizer(), - getMessageIdNormalizer(), - getDurationNormalizer(), - getUserAgentVersionNormalizer()); - } - - default void withCaptureRequestResponseConsoleLogging(Action action) throws Exception { - // Waits for request and response to be logged. - // Due to LoggingFilter to have the highest precedence the response may already be sent when it - // is finished. - CountDownLatch requestResponseCountDownLatch = new CountDownLatch(2); - withCapturedConsoleLogging( - () -> { - action.execute(); - requestResponseCountDownLatch.await(1, TimeUnit.MINUTES); - }, - countDownOnLogbookLogEventFilter(requestResponseCountDownLatch), - Level.TRACE); - } - - private EventFilter countDownOnLogbookLogEventFilter(CountDownLatch countDownLatch) { - return (logEvent) -> { - if (Logbook.class.getName().equals(logEvent.getLoggerName())) { - countDownLatch.countDown(); - } - return true; - }; - } - - private ValidationNormalizer getDateTimeNormalizer() { - return new SimpleRegexReplacement("Date: .+", "Date: MASKED-DATE"); - } - - private ValidationNormalizer getMessageIdNormalizer() { - return new IdNormalizer(new IncrementingIdProvider(), "MASKED-MESSAGE-ID-", "([0-9a-f]{16})"); - } - - private ValidationNormalizer getDurationNormalizer() { - return new SimpleRegexReplacement("Duration: \\d+ ms\n", "Duration: MASKED-DURATION ms\n"); - } - - private ValidationNormalizer getUserAgentVersionNormalizer() { - return new SimpleRegexReplacement("user-agent: .*\n", "user-agent: MASKED-USER-AGENT\n"); - } -} diff --git a/backend/rest-service-errors/build.gradle b/backend/rest-service-errors/build.gradle index 444e557464cfa59bb0f8b8956814f34c63ae08c9..d7c46a8eccb861eafab8d69b58713dbc509eb389 100644 --- a/backend/rest-service-errors/build.gradle +++ b/backend/rest-service-errors/build.gradle @@ -4,7 +4,6 @@ plugins { dependencies { api project(':lib-commons') - implementation project(':api-commons') api 'jakarta.validation:jakarta.validation-api' } diff --git a/backend/rest-service-errors/gradle.lockfile b/backend/rest-service-errors/gradle.lockfile index 06dbb2ff09463c86d7b0f212437a6699ede95eaf..4c6f0e9d20b7d6e4daeb5379dc774ea0b942a13a 100644 --- a/backend/rest-service-errors/gradle.lockfile +++ b/backend/rest-service-errors/gradle.lockfile @@ -1,15 +1,12 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -46,21 +43,20 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorCode.java b/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorCode.java index 7c5ce1abf8b0a7dbc33d0a73f4fba8733d2f01e7..c8c8e6285adbf4e317dffa7ee9aab2ee57f658d2 100644 --- a/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorCode.java +++ b/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorCode.java @@ -28,11 +28,13 @@ public enum ErrorCode { TIMEOUT, /** Use when DataIntegrityViolationException is thrown */ DATA_INTEGRITY_VIOLATION, + /** Use when a resource already exists */ ALREADY_EXISTS, /** Use for Exceptions thrown during aggregation */ AGGREGATION_EXCEPTION, /** Use when given file does not meet requirements */ INVALID_FILE, + /** Use when given PDF file does not meet requirements */ NONCONFORM_PDF, /** Use when data was illegally manipulated */ CORRUPT, diff --git a/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorResponse.java b/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorResponse.java index 8b9f39a0cc7635f6d9d431d250a722d8065c8619..6d1167731a8d55b6c695af68164c2706e1a88d93 100644 --- a/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorResponse.java +++ b/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorResponse.java @@ -5,8 +5,6 @@ package de.eshg.rest.service.error; -import de.eshg.api.commons.CanBeLogged; import jakarta.validation.constraints.NotNull; -public record ErrorResponse( - @CanBeLogged @NotNull ErrorCode errorCode, @CanBeLogged String message) {} +public record ErrorResponse(@NotNull ErrorCode errorCode, String message) {} diff --git a/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorResponseWithLocation.java b/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorResponseWithLocation.java index 24a89396306c589da887711768f1e1f5f50a3214..5dd184a3fbc9166b1cc347a53a0e3ceaa17d04dd 100644 --- a/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorResponseWithLocation.java +++ b/backend/rest-service-errors/src/main/java/de/eshg/rest/service/error/ErrorResponseWithLocation.java @@ -5,10 +5,7 @@ package de.eshg.rest.service.error; -import de.eshg.api.commons.CanBeLogged; import jakarta.validation.constraints.NotNull; public record ErrorResponseWithLocation( - @CanBeLogged @NotNull ErrorCode errorCode, - @CanBeLogged String message, - @CanBeLogged @NotNull String errorLocation) {} + @NotNull ErrorCode errorCode, String message, @NotNull String errorLocation) {} diff --git a/backend/school-entry/build.gradle b/backend/school-entry/build.gradle index d9b45a3e92301791743def442e64c481d169a62a..086778e09bedab306231877ea09768cd696f8ac1 100644 --- a/backend/school-entry/build.gradle +++ b/backend/school-entry/build.gradle @@ -19,6 +19,7 @@ dependencies { implementation 'org.apache.xmlgraphics:batik-svggen:latest.release' implementation 'org.apache.xmlgraphics:batik-dom:latest.release' + implementation 'com.google.guava:guava:latest.release' implementation 'org.apache.commons:commons-csv:latest.release' implementation 'org.springdoc:springdoc-openapi-starter-common:latest.release' annotationProcessor 'org.hibernate.orm:hibernate-jpamodelgen' @@ -29,7 +30,6 @@ dependencies { testImplementation testFixtures(project(':business-module-persistence-commons')) testImplementation 'jakarta.mail:jakarta.mail-api' - testImplementation 'com.google.guava:guava:latest.release' testImplementation 'com.google.zxing:javase:latest.release' testImplementation testFixtures(project(':lib-document-generator')) } @@ -49,4 +49,4 @@ tasks.named("test").configure { dependencyTrack { projectId = project.findProperty('dependency-track-project-id-school-entry') ?: "unspecified" -} \ No newline at end of file +} diff --git a/backend/school-entry/gradle.lockfile b/backend/school-entry/gradle.lockfile index ab465d1ba60207e5cc1f245ab2cddd4f5342cca0..49b8a571fe83db807040af63f2f9c7462deb3669 100644 --- a/backend/school-entry/gradle.lockfile +++ b/backend/school-entry/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.adobe.xmp:xmpcore:6.1.11=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.beust:jcommander:1.82=testCompileClasspath,testRuntimeClasspath com.drewnoakes:metadata-extractor:2.19.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -25,12 +25,12 @@ com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.9.2=testRuntimeC com.github.jai-imageio:jai-imageio-core:1.4.0=testRuntimeClasspath com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.github.virtuald:curvesapi:1.08=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.j2objc:j2objc-annotations:3.0.0=testCompileClasspath +com.google.code.findbugs:jsr305:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.28.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.guava:failureaccess:1.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.zxing:core:3.5.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.zxing:javase:3.5.3=testCompileClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath @@ -53,7 +53,7 @@ com.zaxxer:SparseBitSet:1.3=compileClasspath,productionRuntimeClasspath,runtimeC commons-codec:commons-codec:1.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-logging:commons-logging:1.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -66,11 +66,11 @@ io.github.openhtmltopdf:openhtmltopdf-core:1.1.22=productionRuntimeClasspath,run io.github.openhtmltopdf:openhtmltopdf-pdfbox:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-slf4j:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-svg-support:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -78,7 +78,7 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -86,7 +86,6 @@ jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClass jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.mail:jakarta.mail-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -126,10 +125,10 @@ org.apache.tika:tika-bom:2.9.2=productionRuntimeClasspath,runtimeClasspath,testR org.apache.tika:tika-core:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-pdf-module:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-xmp-commons:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlbeans:xmlbeans:5.2.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-anim:1.17=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-awt-util:1.17=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -158,7 +157,7 @@ org.bouncycastle:bcmail-jdk18on:1.78.1=productionRuntimeClasspath,runtimeClasspa org.bouncycastle:bcpkix-jdk18on:1.78.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.bouncycastle:bcprov-jdk18on:1.78.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.bouncycastle:bcutil-jdk18on:1.78.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.checkerframework:checker-qual:3.43.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.checkerframework:checker-qual:3.43.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.eclipse.angus:angus-activation:2.0.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.eclipse.angus:jakarta.mail:2.0.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.freemarker:freemarker:2.3.33=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -169,9 +168,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -199,7 +198,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -207,30 +206,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -240,19 +239,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/school-entry/openApi.yaml b/backend/school-entry/openApi.yaml index 7c417f2f71a882e29bd740fde393194fdcae7df7..8d45e9164f13036959a8368c169347fb5aeae597 100644 --- a/backend/school-entry/openApi.yaml +++ b/backend/school-entry/openApi.yaml @@ -1475,6 +1475,14 @@ paths: required: false schema: type: boolean + - in: query + name: labelsFilter + required: false + schema: + type: array + items: + type: string + format: uuid - in: query name: sortKey required: false @@ -1697,6 +1705,43 @@ paths: summary: Get the XLSX school list template. tags: - SchoolEntry + /school-entries/waiting-room-procedures: + get: + operationId: getWaitingRoomProcedures + parameters: + - in: query + name: sortKey + required: false + schema: + $ref: "#/components/schemas/WaitingRoomSortKey" + - in: query + name: sortDirection + required: false + schema: + $ref: "#/components/schemas/SortDirection" + - in: query + name: pageNumber + required: false + schema: + type: integer + format: int32 + minimum: 0 + - in: query + name: pageSize + required: false + schema: + type: integer + format: int32 + minimum: 1 + responses: + "200": + content: + '*/*': + schema: + $ref: "#/components/schemas/GetWaitingRoomProceduresResponse" + description: OK + tags: + - SchoolEntry /school-entries/{procedureId}: get: operationId: getProcedure @@ -3255,8 +3300,18 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 required: - assignee + - taskVersion + BooleanWithUnknown: + type: string + enum: + - "TRUE" + - "FALSE" + - UNKNOWN BulkUpdateProceduresArchivingRelevanceRequest: type: object properties: @@ -3306,32 +3361,23 @@ components: type: object properties: u2: - type: boolean - description: "Boolean that indicates, if the U2 screening was carried out" + $ref: "#/components/schemas/BooleanWithUnknown" u3: - type: boolean - description: "Boolean that indicates, if the U3 screening was carried out" + $ref: "#/components/schemas/BooleanWithUnknown" u4: - type: boolean - description: "Boolean that indicates, if the U4 screening was carried out" + $ref: "#/components/schemas/BooleanWithUnknown" u5: - type: boolean - description: "Boolean that indicates, if the U5 screening was carried out" + $ref: "#/components/schemas/BooleanWithUnknown" u6: - type: boolean - description: "Boolean that indicates, if the U6 screening was carried out" + $ref: "#/components/schemas/BooleanWithUnknown" u7: - type: boolean - description: "Boolean that indicates, if the U7 screening was carried out" + $ref: "#/components/schemas/BooleanWithUnknown" u7a: - type: boolean - description: "Boolean that indicates, if the U7A screening was carried out" + $ref: "#/components/schemas/BooleanWithUnknown" u8: - type: boolean - description: "Boolean that indicates, if the U8 screening was carried out" + $ref: "#/components/schemas/BooleanWithUnknown" u9: - type: boolean - description: "Boolean that indicates, if the U9 screening was carried out" + $ref: "#/components/schemas/BooleanWithUnknown" Child: type: object description: "Child representation. In the context of the school entry examination,\ @@ -4801,7 +4847,7 @@ components: - totalPages GetArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - PROCEDURE_TYPE @@ -5144,7 +5190,7 @@ components: - totalPages GetRelevantArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - EXPORTED_AT @@ -5256,6 +5302,19 @@ components: enum: - ASC - DESC + GetWaitingRoomProceduresResponse: + type: object + properties: + elements: + type: array + items: + $ref: "#/components/schemas/WaitingRoomProcedure" + totalNumberOfElements: + type: integer + format: int64 + required: + - elements + - totalNumberOfElements HandednessValue: type: string enum: @@ -6988,6 +7047,11 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 + required: + - taskVersion SocioEducationalPerformance: type: object description: Assessment of the social and educational performance @@ -7164,6 +7228,9 @@ components: $ref: "#/components/schemas/TaskStatus" taskType: $ref: "#/components/schemas/TaskType" + version: + type: integer + format: int64 required: - businessModule - createdAt @@ -7174,6 +7241,7 @@ components: - taskId - taskStatus - taskType + - version TaskMetric: type: object properties: @@ -7535,7 +7603,7 @@ components: items: $ref: "#/components/schemas/OtherVaccination" perkombiHbv: - type: boolean + $ref: "#/components/schemas/BooleanWithUnknown" pertussis: type: integer format: int32 @@ -7633,6 +7701,36 @@ components: \ is incremented by one." required: - version + WaitingRoomProcedure: + type: object + properties: + child: + $ref: "#/components/schemas/Child" + id: + type: string + format: uuid + description: Id of the Procedure. + example: ae9831d4-dc25-48d8-9bfe-4c0b54bfb2c1 + modifiedAt: + type: string + format: date-time + waitingRoom: + $ref: "#/components/schemas/WaitingRoom" + required: + - child + - id + - modifiedAt + - waitingRoom + WaitingRoomSortKey: + type: string + enum: + - ID + - DATE_OF_BIRTH + - FIRSTNAME + - LASTNAME + - STATUS + - INFO + - MODIFIED_AT WaitingStatus: type: string enum: diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/PagedWaitingRoomProcedures.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/PagedWaitingRoomProcedures.java new file mode 100644 index 0000000000000000000000000000000000000000..2562c999783f95358f498c06db1ac9d8a7c93bbc --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/PagedWaitingRoomProcedures.java @@ -0,0 +1,17 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry; + +import de.eshg.schoolentry.business.model.WaitingRoomProcedureData; +import java.util.List; +import java.util.stream.Stream; + +record PagedWaitingRoomProcedures( + List<WaitingRoomProcedureData> proceduresPage, long totalNumberOfProcedures) { + public Stream<WaitingRoomProcedureData> stream() { + return proceduresPage.stream(); + } +} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/ProceduresHelper.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/ProceduresHelper.java index 159ae2b88a97255b628cd846b618bce5495b040f..7090b9003857804b8bc13db29005c7754a6e9dcf 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/ProceduresHelper.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/ProceduresHelper.java @@ -16,13 +16,16 @@ import de.eshg.schoolentry.api.ProcedureFilterParameters; import de.eshg.schoolentry.api.SchoolDto; import de.eshg.schoolentry.business.model.ProcedureData; import de.eshg.schoolentry.business.model.ProcedureWithChildData; +import de.eshg.schoolentry.business.model.WaitingRoomProcedureData; import de.eshg.schoolentry.client.PersonClient; import de.eshg.schoolentry.domain.model.SchoolEntryProcedure; import de.eshg.schoolentry.domain.model.SchoolEntryProcedure_; import de.eshg.schoolentry.domain.repository.SchoolEntryProcedureRepository; import de.eshg.schoolentry.domain.specification.SchoolEntryProcedureSpecification; +import de.eshg.schoolentry.domain.specification.WaitingRoomSpecification; import de.eshg.schoolentry.mapper.ProcedureMapper; import de.eshg.schoolentry.util.ProcedureSortKey; +import de.eshg.schoolentry.util.WaitingRoomSortKey; import jakarta.persistence.EntityManager; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; @@ -31,11 +34,7 @@ import jakarta.persistence.criteria.Root; import java.time.Clock; import java.time.Instant; import java.time.LocalDate; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import java.util.stream.Stream; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -64,6 +63,51 @@ class ProceduresHelper { this.clock = clock; } + PagedWaitingRoomProcedures getWaitingRoomProcedures(WaitingRoomPageSpec pageSpec) { + WaitingRoomSpecification waitingRoomSpecification = + new WaitingRoomSpecification(pageSpec.sortKey(), pageSpec.direction()); + + if (!pageSpec.sortKey().isPersonAttribute()) { + Page<SchoolEntryProcedure> schoolEntryProcedures = + schoolEntryProcedureRepository.findAll( + waitingRoomSpecification, PageRequest.of(pageSpec.pageNumber(), pageSpec.pageSize())); + List<WaitingRoomProcedureData> procedureData = + augmentWithWaitingRoomData(schoolEntryProcedures.getContent()).toList(); + return new PagedWaitingRoomProcedures( + procedureData, schoolEntryProcedures.getTotalElements()); + } + + List<UUID> personIds = findAllChildIds(waitingRoomSpecification); + + List<UUID> pagedAndSortedChildIds = + personClient + .fetchPersonsBulk( + personIds, + mapToGetPersonsSortKey(pageSpec.sortKey()), + pageSpec.direction(), + pageSpec.pageNumber(), + pageSpec.pageSize()) + .stream() + .map(AddPersonFileStateResponse::id) + .toList(); + + List<SchoolEntryProcedure> result = + schoolEntryProcedureRepository + .findByRelatedPersons(pagedAndSortedChildIds) + .sorted( + Comparator.comparingInt( + procedure -> { + int index = + pagedAndSortedChildIds.indexOf(procedure.getChildIdFromCentralFile()); + Assert.isTrue(index >= 0, "Unexpected index: " + index); + return index; + })) + .toList(); + + List<WaitingRoomProcedureData> procedureData = augmentWithWaitingRoomData(result).toList(); + return new PagedWaitingRoomProcedures(procedureData, personIds.size()); + } + PagedProcedures getOpenSchoolEntryProcedures( ProcedureFilterParameters filterParameters, ProcedurePageSpec pageSpec) { SchoolEntryProcedureSpecification schoolEntryProcedureSpecification = @@ -74,6 +118,10 @@ class ProceduresHelper { ProcedureMapper.mapIntegerToYear(filterParameters.schoolYearFilter()), getDayOfAppointmentAsInstant(filterParameters.dayOfAppointmentFilter()), filterParameters.hasAppointmentFilter(), + new ArrayList<>( + filterParameters.labelsFilter() == null + ? Collections.emptyList() + : filterParameters.labelsFilter()), pageSpec.sortKey(), pageSpec.direction()); @@ -128,6 +176,16 @@ class ProceduresHelper { }; } + private static GetPersonsSortKey mapToGetPersonsSortKey(WaitingRoomSortKey sortKey) { + return switch (sortKey) { + case DATE_OF_BIRTH -> GetPersonsSortKey.DATE_OF_BIRTH; + case FIRSTNAME -> GetPersonsSortKey.FIRST_NAME; + case LASTNAME -> GetPersonsSortKey.LAST_NAME; + case ID, INFO, STATUS, MODIFIED_AT -> + throw new IllegalArgumentException("Unexpected sort key: " + sortKey); + }; + } + private List<UUID> findAllChildIds( SchoolEntryProcedureSpecification schoolEntryProcedureSpecification) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); @@ -146,6 +204,23 @@ class ProceduresHelper { return entityManager.createQuery(query).getResultList(); } + private List<UUID> findAllChildIds(WaitingRoomSpecification waitingRoomSpecification) { + CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); + CriteriaQuery<UUID> query = criteriaBuilder.createQuery(UUID.class); + Root<SchoolEntryProcedure> root = query.from(SchoolEntryProcedure.class); + + Join<?, ?> relatedPersonsJoin = root.join(SchoolEntryProcedure_.RELATED_PERSONS); + Join<?, ?> childJoin = + relatedPersonsJoin.on( + criteriaBuilder.equal( + relatedPersonsJoin.get(RelatedPerson_.PERSON_TYPE), PersonType.PATIENT)); + query.select(childJoin.get(RelatedPerson_.CENTRAL_FILE_STATE_ID)); + + query.where(waitingRoomSpecification.toPredicate(root, query, criteriaBuilder)); + + return entityManager.createQuery(query).getResultList(); + } + private Instant getDayOfAppointmentAsInstant(LocalDate dayOfAppointmentFilter) { if (dayOfAppointmentFilter == null) { return null; @@ -153,6 +228,20 @@ class ProceduresHelper { return dayOfAppointmentFilter.atStartOfDay(clock.getZone()).toInstant(); } + Stream<WaitingRoomProcedureData> augmentWithWaitingRoomData( + List<SchoolEntryProcedure> procedures) { + return personClient + .augmentWithChildData(procedures) + .map( + data -> + new WaitingRoomProcedureData( + data.procedure().getId(), + data.procedure().getExternalId(), + data.child(), + data.procedure().getWaitingRoom(), + data.procedure().getWaitingRoom().getModifiedAt())); + } + Stream<ProcedureData> augmentWithChildData(List<SchoolEntryProcedure> procedures) { List<SchoolDto> schools = getSchools(procedures); diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryCitizenService.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryCitizenService.java index 2e30f1afeae083d1a82524a7f1142633dbda6bf1..e6c267ff184bcaa1c45c88261070c4c38248abec 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryCitizenService.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryCitizenService.java @@ -53,7 +53,7 @@ public class SchoolEntryCitizenService { SchoolEntryService schoolEntryService, AppointmentBlockSlotUtil appointmentBlockSlotUtil) { this.clock = clock; - this.citizensProperties = schoolEntryProperties.citizens(); + this.citizensProperties = schoolEntryProperties.getCitizens(); this.schoolEntryProcedureRepository = schoolEntryProcedureRepository; this.schoolEntryService = schoolEntryService; this.appointmentBlockSlotUtil = appointmentBlockSlotUtil; diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryController.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryController.java index c78421158e30a44f8c2a51a3f1ecc1e2a1aeaafa..3b871fed6f629cd4f796b13b9c4efe7c73b4312f 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryController.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryController.java @@ -482,6 +482,8 @@ public class SchoolEntryController { validateSheet(workbook); Sheet sheet = workbook.getSheetAt(0); + + validator.validateNumberOfRows(sheet); validateHeaderExists(sheet); switch (importType) { case CITIZEN_LIST -> ImportDataUtil.validateCitizenListHeaderFormat(sheet); @@ -644,6 +646,7 @@ public class SchoolEntryController { public WaitingRoomDto updateWaitingRoomDetails( @PathVariable("procedureId") UUID procedureId, @Valid @RequestBody WaitingRoomDto request) { featureToggle.assertNewFeatureIsEnabled(SchoolEntryFeature.WAITING_ROOM); + assertLocationModeNotSet(); WaitingRoom waitingRoom = schoolEntryService.findWaitingRoomForUpdate(procedureId, request.version()); SchoolEntryProcedure procedure = waitingRoom.getProcedure(); @@ -674,4 +677,25 @@ public class SchoolEntryController { return ResponseEntity.ok(new ValidateRequiredProcedureDataResponse(incompleteAreas)); } + + @GetMapping("/waiting-room-procedures") + @Transactional(readOnly = true) + public GetWaitingRoomProceduresResponse getWaitingRoomProcedures( + @InlineParameterObject @ParameterObject @Valid + WaitingRoomProcedurePaginationAndSortParameters paginationAndSortParameters) { + featureToggle.assertNewFeatureIsEnabled(SchoolEntryFeature.WAITING_ROOM); + assertLocationModeNotSet(); + + PagedWaitingRoomProcedures pagedProcedures = + schoolEntryService.getWaitingRoomProcedures(paginationAndSortParameters); + return new GetWaitingRoomProceduresResponse( + pagedProcedures.stream().map(WaitingRoomMapper::mapWaitingRoomProcedureToDto).toList(), + pagedProcedures.totalNumberOfProcedures()); + } + + private void assertLocationModeNotSet() { + if (appointmentBlockProperties.getLocationSelectionMode() != LocationSelectionMode.NONE) { + throw ExceptionUtil.badRequestExceptionUnsupportedLocationMode(); + } + } } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryService.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryService.java index bf41aa4c2314b8a82d215c2e74df5176be6f7655..aea9d74c09ef26857ddbc8b88c9b88a99aab7f87 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryService.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/SchoolEntryService.java @@ -47,6 +47,7 @@ import de.eshg.schoolentry.importer.ImportType; import de.eshg.schoolentry.mapper.AppointmentMapper; import de.eshg.schoolentry.mapper.PersonMapper; import de.eshg.schoolentry.mapper.ProcedureMapper; +import de.eshg.schoolentry.mapper.WaitingRoomMapper; import de.eshg.schoolentry.pdf.ReportGeneratorConstants; import de.eshg.schoolentry.pdf.invitation.InvitationGenerator; import de.eshg.schoolentry.percentiles.PercentileCalculationService; @@ -421,7 +422,9 @@ public class SchoolEntryService { CitizenAccessCodeUserDto citizenAccessCodeUser = createOrGetCitizenAccessCodeUser(procedure); String accessCode = citizenAccessCodeUser.accessCode(); - Pdf invitation = invitationGenerator.generateInvitation(accessCode, childData, start); + Pdf invitation = + invitationGenerator.generateInvitation( + accessCode, childData, start, getAppointmentLocation(procedure)); ProgressEntryUtil.addProgressEntry( procedure, APPOINTMENT_MODIFIED, @@ -463,7 +466,7 @@ public class SchoolEntryService { } else { Instant now = Instant.now(clock); Instant earliestStart = - now.plus(schoolEntryProperties.bulkCreateAppointmentsMinLeadTime()); + now.plus(schoolEntryProperties.getBulkCreateAppointmentsMinLeadTime()); AppointmentType appointmentType = computeAppointmentType(procedure, null, null); List<AppointmentDto> freeAppointments = @@ -485,6 +488,22 @@ public class SchoolEntryService { return stats; } + PagedWaitingRoomProcedures getWaitingRoomProcedures( + WaitingRoomProcedurePaginationAndSortParameters paginationAndSortParameters) { + WaitingRoomPageSpec pageSpec = createWaitingRoomPageSpec(paginationAndSortParameters); + return proceduresHelper.getWaitingRoomProcedures(pageSpec); + } + + private WaitingRoomPageSpec createWaitingRoomPageSpec( + WaitingRoomProcedurePaginationAndSortParameters paginationAndSortParameters) { + + return WaitingRoomMapper.mapToPageSpec( + paginationAndSortParameters.pageNumberOrFallback(0), + paginationAndSortParameters.pageSizeOrFallback(25), + paginationAndSortParameters.sortKeyOrFallback(WaitingRoomSortKey.ID), + paginationAndSortParameters.sortDirectionOrFallback(SortDirection.DESC)); + } + PagedProcedures getProcedures( ProcedureFilterParameters filterParameters, ProcedurePaginationAndSortParameters paginationAndSortParameters, @@ -1452,17 +1471,17 @@ public class SchoolEntryService { @VisibleForTesting boolean isRegularSchoolEntry(LocalDate dateOfBirth, Year schoolYear) { MonthDay maxDateOfBirthForRegularSchoolEntry = - schoolEntryProperties.maxDateOfBirthForRegularSchoolEntry(); + schoolEntryProperties.getMaxDateOfBirthForRegularSchoolEntry(); if (schoolEntryFeatureToggle.isNewFeatureEnabled(SchoolEntryFeature.SCHOOL_YEAR)) { LocalDate maxDateOfBirthForRegularSchoolEntryWithYear = schoolYear.minusYears(6).atMonthDay(maxDateOfBirthForRegularSchoolEntry); - if (schoolEntryProperties.maxDateOfBirthForRegularSchoolEntryIsInclusive()) { + if (schoolEntryProperties.isMaxDateOfBirthForRegularSchoolEntryIsInclusive()) { return !dateOfBirth.isAfter(maxDateOfBirthForRegularSchoolEntryWithYear); } else { return dateOfBirth.isBefore(maxDateOfBirthForRegularSchoolEntryWithYear); } } else { - if (schoolEntryProperties.maxDateOfBirthForRegularSchoolEntryIsInclusive()) { + if (schoolEntryProperties.isMaxDateOfBirthForRegularSchoolEntryIsInclusive()) { return MonthDay.from(dateOfBirth).compareTo(maxDateOfBirthForRegularSchoolEntry) <= 0; } else { return MonthDay.from(dateOfBirth).compareTo(maxDateOfBirthForRegularSchoolEntry) < 0; diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/Validator.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/Validator.java index e5f99be539f3865d1d53c73f7a649bf7d3c1bca4..cb157460b7c375328641698ae5f5dbddd63aeac5 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/Validator.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/Validator.java @@ -17,12 +17,14 @@ import de.eshg.lib.appointmentblock.api.AppointmentDto; import de.eshg.lib.procedure.domain.model.ProcedureStatus; import de.eshg.lib.procedure.domain.model.ProcedureType; import de.eshg.rest.service.error.BadRequestException; +import de.eshg.rest.service.error.ErrorCode; import de.eshg.schoolentry.api.*; import de.eshg.schoolentry.api.anamnesis.AnamnesisDto; import de.eshg.schoolentry.business.model.ChildData; import de.eshg.schoolentry.business.model.ProcedureDetailsData; import de.eshg.schoolentry.config.SchoolEntryFeature; import de.eshg.schoolentry.config.SchoolEntryFeatureToggle; +import de.eshg.schoolentry.config.SchoolEntryProperties; import de.eshg.schoolentry.domain.model.SchoolEntryProcedure; import de.eshg.schoolentry.domain.repository.Icd10CodeRepository; import de.eshg.schoolentry.domain.repository.Icd10GroupRepository; @@ -34,6 +36,7 @@ import java.util.List; import java.util.Objects; import java.util.UUID; import org.apache.commons.lang3.BooleanUtils; +import org.apache.poi.ss.usermodel.Sheet; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -58,18 +61,21 @@ public class Validator { private final ContactClient contactClient; private final Clock clock; private final SchoolEntryFeatureToggle featureToggle; + private final SchoolEntryProperties schoolEntryProperties; public Validator( Icd10CodeRepository icd10CodeRepository, Icd10GroupRepository icd10GroupRepository, ContactClient contactClient, Clock clock, - SchoolEntryFeatureToggle featureToggle) { + SchoolEntryFeatureToggle featureToggle, + SchoolEntryProperties schoolEntryProperties) { this.icd10CodeRepository = icd10CodeRepository; this.icd10GroupRepository = icd10GroupRepository; this.contactClient = contactClient; this.clock = clock; this.featureToggle = featureToggle; + this.schoolEntryProperties = schoolEntryProperties; } void validateSearchParametersAreNull(ProcedureSearchParameters searchParameters) { @@ -541,4 +547,13 @@ public class Validator { "Procedure %s cannot be deleted.".formatted(procedureDetailsData.externalId())); } } + + public void validateNumberOfRows(Sheet sheet) { + if (sheet.getPhysicalNumberOfRows() > schoolEntryProperties.getMaxNumberOfImportRows()) { + throw new BadRequestException( + ErrorCode.INVALID_FILE, + "Invalid file structure. At most %s rows are allowed." + .formatted(schoolEntryProperties.getMaxNumberOfImportRows())); + } + } } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/WaitingRoomPageSpec.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/WaitingRoomPageSpec.java new file mode 100644 index 0000000000000000000000000000000000000000..ac8e9de1c34d5ac041ce854f2b920719a95828de --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/WaitingRoomPageSpec.java @@ -0,0 +1,12 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry; + +import de.eshg.schoolentry.util.WaitingRoomSortKey; +import org.springframework.data.domain.Sort; + +public record WaitingRoomPageSpec( + int pageNumber, int pageSize, WaitingRoomSortKey sortKey, Sort.Direction direction) {} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/BooleanWithUnknownDto.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/BooleanWithUnknownDto.java new file mode 100644 index 0000000000000000000000000000000000000000..3164756e8b4045e16ec4c1879e9e18d0c8b6f3b2 --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/BooleanWithUnknownDto.java @@ -0,0 +1,15 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.api; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(name = "BooleanWithUnknown") +public enum BooleanWithUnknownDto { + TRUE, + FALSE, + UNKNOWN +} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/CheckUpsDto.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/CheckUpsDto.java index aa268494dfa6e3f4a2ca50a65fcf9e754b904848..a07e7fbae5ce8f50279ba8e87cf69d8f1b41bd0d 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/CheckUpsDto.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/CheckUpsDto.java @@ -9,17 +9,24 @@ import io.swagger.v3.oas.annotations.media.Schema; @Schema(name = "CheckUps") public record CheckUpsDto( - @Schema(description = "Boolean that indicates, if the U2 screening was carried out") Boolean u2, - @Schema(description = "Boolean that indicates, if the U3 screening was carried out") Boolean u3, - @Schema(description = "Boolean that indicates, if the U4 screening was carried out") Boolean u4, - @Schema(description = "Boolean that indicates, if the U5 screening was carried out") Boolean u5, - @Schema(description = "Boolean that indicates, if the U6 screening was carried out") Boolean u6, - @Schema(description = "Boolean that indicates, if the U7 screening was carried out") Boolean u7, + @Schema(description = "Boolean that indicates, if the U2 screening was carried out") + BooleanWithUnknownDto u2, + @Schema(description = "Boolean that indicates, if the U3 screening was carried out") + BooleanWithUnknownDto u3, + @Schema(description = "Boolean that indicates, if the U4 screening was carried out") + BooleanWithUnknownDto u4, + @Schema(description = "Boolean that indicates, if the U5 screening was carried out") + BooleanWithUnknownDto u5, + @Schema(description = "Boolean that indicates, if the U6 screening was carried out") + BooleanWithUnknownDto u6, + @Schema(description = "Boolean that indicates, if the U7 screening was carried out") + BooleanWithUnknownDto u7, @Schema(description = "Boolean that indicates, if the U7A screening was carried out") - Boolean u7a, - @Schema(description = "Boolean that indicates, if the U8 screening was carried out") Boolean u8, + BooleanWithUnknownDto u7a, + @Schema(description = "Boolean that indicates, if the U8 screening was carried out") + BooleanWithUnknownDto u8, @Schema(description = "Boolean that indicates, if the U9 screening was carried out") - Boolean u9) { + BooleanWithUnknownDto u9) { public CheckUpsDto() { this(null, null, null, null, null, null, null, null, null); } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/GetWaitingRoomProceduresResponse.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/GetWaitingRoomProceduresResponse.java new file mode 100644 index 0000000000000000000000000000000000000000..76086a3257acaca70fb3db4fedcc084c6f93ef7c --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/GetWaitingRoomProceduresResponse.java @@ -0,0 +1,17 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.api; + +import de.eshg.base.PagedResponse; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.util.List; + +@Schema(name = "GetWaitingRoomProceduresResponse") +public record GetWaitingRoomProceduresResponse( + @Valid @NotNull List<WaitingRoomProcedureDto> elements, @NotNull long totalNumberOfElements) + implements PagedResponse<WaitingRoomProcedureDto> {} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/ProcedureFilterParameters.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/ProcedureFilterParameters.java index 400788f04173ae477e804cb616db7f4aafd40743..70c6524158a178c9813aed4c912d94d18845d46f 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/ProcedureFilterParameters.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/ProcedureFilterParameters.java @@ -7,6 +7,7 @@ package de.eshg.schoolentry.api; import jakarta.validation.constraints.Min; import java.time.LocalDate; +import java.util.List; import java.util.UUID; public record ProcedureFilterParameters( @@ -14,4 +15,5 @@ public record ProcedureFilterParameters( UUID schoolIdFilter, @Min(1900) Integer schoolYearFilter, LocalDate dayOfAppointmentFilter, - Boolean hasAppointmentFilter) {} + Boolean hasAppointmentFilter, + List<UUID> labelsFilter) {} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/SchoolEntryProcedureSortKey.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/SchoolEntryProcedureSortKey.java index 44d7cbc6958dbb0293249878b06d737ec9df3728..c7be7480edf1cf4ed36108b0624dcd6697fc7a66 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/SchoolEntryProcedureSortKey.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/SchoolEntryProcedureSortKey.java @@ -5,7 +5,6 @@ package de.eshg.schoolentry.api; -// Unusual naming to match the corresponding field names in frontend. public enum SchoolEntryProcedureSortKey { ID, DATE_OF_BIRTH, diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/VaccinationStatusDto.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/VaccinationStatusDto.java index 163c180b5051a8b1b2daab61d2f79d934f74d3b1..d4aca47a7f36c2b0f7608cabe2ee560e95dec1d0 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/VaccinationStatusDto.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/VaccinationStatusDto.java @@ -41,4 +41,4 @@ public record VaccinationStatusDto( List<OtherVaccinationDto> otherVaccinations, @Schema(description = "Boolean that indicates, if the vaccination pass was shown or not.") Boolean vaccinationPassPresented, - Boolean perkombiHbv) {} + BooleanWithUnknownDto perkombiHbv) {} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/WaitingRoomProcedureDto.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/WaitingRoomProcedureDto.java new file mode 100644 index 0000000000000000000000000000000000000000..a344998f755d22b9bc9633d87573f501089e54e5 --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/WaitingRoomProcedureDto.java @@ -0,0 +1,20 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.api; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; +import java.util.UUID; + +@Schema(name = "WaitingRoomProcedure") +public record WaitingRoomProcedureDto( + @NotNull UUID id, + @NotNull @Valid ChildDto child, + @NotNull @Valid WaitingRoomDto waitingRoom, + @NotNull Instant modifiedAt) + implements ProcedureBaseDto {} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/WaitingRoomProcedurePaginationAndSortParameters.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/WaitingRoomProcedurePaginationAndSortParameters.java new file mode 100644 index 0000000000000000000000000000000000000000..0e7e1689dd82d48cf192cf1be35f1c02a1134649 --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/WaitingRoomProcedurePaginationAndSortParameters.java @@ -0,0 +1,18 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.api; + +import de.eshg.base.PaginationParameters; +import de.eshg.base.SortDirection; +import de.eshg.base.SortParameters; +import jakarta.validation.constraints.Min; + +public record WaitingRoomProcedurePaginationAndSortParameters( + WaitingRoomSortKey sortKey, + SortDirection sortDirection, + @Min(0) Integer pageNumber, + @Min(1) Integer pageSize) + implements PaginationParameters, SortParameters<WaitingRoomSortKey> {} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/api/WaitingRoomSortKey.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/WaitingRoomSortKey.java new file mode 100644 index 0000000000000000000000000000000000000000..d72b0e657d1b43d9a6e16f664c374bfb19021aba --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/api/WaitingRoomSortKey.java @@ -0,0 +1,16 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.api; + +public enum WaitingRoomSortKey { + ID, + DATE_OF_BIRTH, + FIRSTNAME, + LASTNAME, + STATUS, + INFO, + MODIFIED_AT, +} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/business/model/WaitingRoomProcedureData.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/business/model/WaitingRoomProcedureData.java new file mode 100644 index 0000000000000000000000000000000000000000..6fb75dd50a2e65d53158c4f2b4531de2d13281f6 --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/business/model/WaitingRoomProcedureData.java @@ -0,0 +1,17 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.business.model; + +import de.eshg.schoolentry.domain.model.WaitingRoom; +import java.time.Instant; +import java.util.UUID; + +public record WaitingRoomProcedureData( + Long internalId, + UUID externalId, + ChildData child, + WaitingRoom waitingRoom, + Instant modifiedAt) {} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/client/PersonClient.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/client/PersonClient.java index 566baae3f03dad35b8b11f10b973f7634d1cd978..082d6553d9d2a1c1fdc3a0c48e205485aeeb7400 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/client/PersonClient.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/client/PersonClient.java @@ -5,6 +5,7 @@ package de.eshg.schoolentry.client; +import com.google.common.collect.Lists; import de.cronn.commons.lang.StreamUtil; import de.eshg.base.CountryCodeDto; import de.eshg.base.SortDirection; @@ -44,6 +45,9 @@ public class PersonClient { private static final Logger log = LoggerFactory.getLogger(PersonClient.class); + // Needs to be aligned with the constraint of AddPersonFileStatesRequest.persons + private static final int MAX_PERSONS_PER_BATCH = 10_000; + private final PersonApi personApi; private final Map<UUID, GetPersonFileStateResponse> personCache = new ConcurrentHashMap<>(); @@ -57,14 +61,21 @@ public class PersonClient { return List.of(); } - AddPersonFileStatesRequest request = - new AddPersonFileStatesRequest(mapToFlatRequestList(procedureData, dataOrigin)); - log.info("Creating persons in the central file"); - GetPersonFileStatesResponse response = personApi.addPersonFileStates(request); + List<AddPersonFileStateRequest> personsToAdd = mapToFlatRequestList(procedureData, dataOrigin); + List<UUID> ids = - response.personFileStates().stream().map(AddPersonFileStateResponse::id).toList(); + Lists.partition(personsToAdd, MAX_PERSONS_PER_BATCH).stream() + .flatMap( + personsToAddPartition -> { + AddPersonFileStatesRequest request = + new AddPersonFileStatesRequest(personsToAddPartition); + + AddPersonFileStatesResponse response = personApi.addPersonFileStates(request); + return response.personFileStateIds().stream(); + }) + .toList(); log.info( "Created {} persons in the central file with IDs={}", @@ -104,9 +115,9 @@ public class PersonClient { public List<UUID> createCustodiansInCentralFile(List<ImportCustodianData> custodianData) { List<AddPersonFileStateRequest> requests = mapToPersonFileStateRequest(custodianData, DataOrigin.DATA_IMPORT); - GetPersonFileStatesResponse response = + AddPersonFileStatesResponse response = personApi.addPersonFileStates(new AddPersonFileStatesRequest(requests)); - return response.personFileStates().stream().map(AddPersonFileStateResponse::id).toList(); + return response.personFileStateIds(); } public UUID updatePersonInCentralFile(UpdatePersonRequest custodian, UUID centralFileStateId) { diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/config/SchoolEntryProperties.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/config/SchoolEntryProperties.java index 6165e8e36d31dad41b218d318fb4179375b837e9..dfc7e859115e4ab5d8cce6ed5459e8788b1ac939 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/config/SchoolEntryProperties.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/config/SchoolEntryProperties.java @@ -5,6 +5,7 @@ package de.eshg.schoolentry.config; +import de.eshg.testhelper.ResettableProperties; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import java.time.MonthDay; @@ -14,11 +15,55 @@ import org.springframework.validation.annotation.Validated; @Validated @ConfigurationProperties(prefix = "de.eshg.schoolentry") -public record SchoolEntryProperties( - @NotNull Period bulkCreateAppointmentsMinLeadTime, - @NotNull @Valid Citizens citizens, - @NotNull MonthDay maxDateOfBirthForRegularSchoolEntry, - boolean maxDateOfBirthForRegularSchoolEntryIsInclusive) { +public final class SchoolEntryProperties implements ResettableProperties { + + private @NotNull Period bulkCreateAppointmentsMinLeadTime; + private @NotNull @Valid Citizens citizens; + private @NotNull MonthDay maxDateOfBirthForRegularSchoolEntry; + private boolean maxDateOfBirthForRegularSchoolEntryIsInclusive; + private @NotNull Integer maxNumberOfImportRows = 10_000; + + public Period getBulkCreateAppointmentsMinLeadTime() { + return bulkCreateAppointmentsMinLeadTime; + } + + public Citizens getCitizens() { + return citizens; + } + + public MonthDay getMaxDateOfBirthForRegularSchoolEntry() { + return maxDateOfBirthForRegularSchoolEntry; + } + + public boolean isMaxDateOfBirthForRegularSchoolEntryIsInclusive() { + return maxDateOfBirthForRegularSchoolEntryIsInclusive; + } + + public Integer getMaxNumberOfImportRows() { + return maxNumberOfImportRows; + } + + public void setMaxNumberOfImportRows(Integer maxNumberOfImportRows) { + this.maxNumberOfImportRows = maxNumberOfImportRows; + } + + public void setMaxDateOfBirthForRegularSchoolEntryIsInclusive( + boolean maxDateOfBirthForRegularSchoolEntryIsInclusive) { + this.maxDateOfBirthForRegularSchoolEntryIsInclusive = + maxDateOfBirthForRegularSchoolEntryIsInclusive; + } + + public void setMaxDateOfBirthForRegularSchoolEntry(MonthDay maxDateOfBirthForRegularSchoolEntry) { + this.maxDateOfBirthForRegularSchoolEntry = maxDateOfBirthForRegularSchoolEntry; + } + + public void setCitizens(Citizens citizens) { + this.citizens = citizens; + } + + public void setBulkCreateAppointmentsMinLeadTime(Period bulkCreateAppointmentsMinLeadTime) { + this.bulkCreateAppointmentsMinLeadTime = bulkCreateAppointmentsMinLeadTime; + } public record Citizens( @NotNull Period freeAppointmentsMinLeadTime, @NotNull Period freeAppointmentsMaxLeadTime) {} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/Anamnesis.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/Anamnesis.java index c7e0443f922df613990765d86cecaaee86777a7d..fc1b3c0c3c3a58bae32fb89fc246b24b8fc25d67 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/Anamnesis.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/Anamnesis.java @@ -39,15 +39,32 @@ public class Anamnesis extends GenericEntity<Long> implements ValidatableEntity private Boolean gestationalAge; - private Boolean u2; - private Boolean u3; - private Boolean u4; - private Boolean u5; - private Boolean u6; - private Boolean u7; - private Boolean u7a; - private Boolean u8; - private Boolean u9; + @JdbcType(PostgreSQLEnumJdbcType.class) + private BooleanWithUnknown u2; + + @JdbcType(PostgreSQLEnumJdbcType.class) + private BooleanWithUnknown u3; + + @JdbcType(PostgreSQLEnumJdbcType.class) + private BooleanWithUnknown u4; + + @JdbcType(PostgreSQLEnumJdbcType.class) + private BooleanWithUnknown u5; + + @JdbcType(PostgreSQLEnumJdbcType.class) + private BooleanWithUnknown u6; + + @JdbcType(PostgreSQLEnumJdbcType.class) + private BooleanWithUnknown u7; + + @JdbcType(PostgreSQLEnumJdbcType.class) + private BooleanWithUnknown u7a; + + @JdbcType(PostgreSQLEnumJdbcType.class) + private BooleanWithUnknown u8; + + @JdbcType(PostgreSQLEnumJdbcType.class) + private BooleanWithUnknown u9; private Boolean earlySupport; private Boolean integrationPlace; @@ -161,75 +178,75 @@ public class Anamnesis extends GenericEntity<Long> implements ValidatableEntity this.gestationalAge = gestationalAge; } - public Boolean getU2() { + public BooleanWithUnknown getU2() { return u2; } - public void setU2(Boolean u2) { + public void setU2(BooleanWithUnknown u2) { this.u2 = u2; } - public Boolean getU3() { + public BooleanWithUnknown getU3() { return u3; } - public void setU3(Boolean u3) { + public void setU3(BooleanWithUnknown u3) { this.u3 = u3; } - public Boolean getU4() { + public BooleanWithUnknown getU4() { return u4; } - public void setU4(Boolean u4) { + public void setU4(BooleanWithUnknown u4) { this.u4 = u4; } - public Boolean getU5() { + public BooleanWithUnknown getU5() { return u5; } - public void setU5(Boolean u5) { + public void setU5(BooleanWithUnknown u5) { this.u5 = u5; } - public Boolean getU6() { + public BooleanWithUnknown getU6() { return u6; } - public void setU6(Boolean u6) { + public void setU6(BooleanWithUnknown u6) { this.u6 = u6; } - public Boolean getU7() { + public BooleanWithUnknown getU7() { return u7; } - public void setU7(Boolean u7) { + public void setU7(BooleanWithUnknown u7) { this.u7 = u7; } - public Boolean getU7a() { + public BooleanWithUnknown getU7a() { return u7a; } - public void setU7a(Boolean u7a) { + public void setU7a(BooleanWithUnknown u7a) { this.u7a = u7a; } - public Boolean getU8() { + public BooleanWithUnknown getU8() { return u8; } - public void setU8(Boolean u8) { + public void setU8(BooleanWithUnknown u8) { this.u8 = u8; } - public Boolean getU9() { + public BooleanWithUnknown getU9() { return u9; } - public void setU9(Boolean u9) { + public void setU9(BooleanWithUnknown u9) { this.u9 = u9; } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/BooleanWithUnknown.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/BooleanWithUnknown.java new file mode 100644 index 0000000000000000000000000000000000000000..c1f010a0689a552b907d1ba10b89ade7db8c2689 --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/BooleanWithUnknown.java @@ -0,0 +1,12 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.domain.model; + +public enum BooleanWithUnknown { + TRUE, + FALSE, + UNKNOWN +} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/VaccinationStatus.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/VaccinationStatus.java index 009d55fff662f4794acd399bff7759c4d3a84569..157aa3cb20286728ff26873eea6a4996c188ed46 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/VaccinationStatus.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/VaccinationStatus.java @@ -43,7 +43,9 @@ public class VaccinationStatus extends GenericEntity<Long> implements Validatabl private Integer rota; private Integer tbe; private Integer hepatitisA; - private Boolean perkombiHbv; + + @JdbcType(PostgreSQLEnumJdbcType.class) + private BooleanWithUnknown perkombiHbv; @ElementCollection @CollectionTable( @@ -199,11 +201,11 @@ public class VaccinationStatus extends GenericEntity<Long> implements Validatabl this.vaccinationPassPresented = vaccinationPassPresented; } - public Boolean getPerkombiHbv() { + public BooleanWithUnknown getPerkombiHbv() { return perkombiHbv; } - public void setPerkombiHbv(Boolean perkombiHbv) { + public void setPerkombiHbv(BooleanWithUnknown perkombiHbv) { this.perkombiHbv = perkombiHbv; } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/WaitingRoom.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/WaitingRoom.java index 4bddc66b8882e496e8a1320160194fec289d591e..2312dcb37e3ccf10aeef2c8372d534e7b2ced7a5 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/WaitingRoom.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/model/WaitingRoom.java @@ -8,14 +8,16 @@ package de.eshg.schoolentry.domain.model; import de.eshg.domain.model.GenericEntity; import de.eshg.lib.common.DataSensitivity; import de.eshg.lib.common.SensitivityLevel; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.MapsId; -import jakarta.persistence.OneToOne; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; import org.hibernate.annotations.JdbcType; import org.hibernate.dialect.PostgreSQLEnumJdbcType; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; @Entity +@EntityListeners(AuditingEntityListener.class) @DataSensitivity(SensitivityLevel.SENSITIVE) public class WaitingRoom extends GenericEntity<Long> { @Id private Long id; @@ -29,6 +31,8 @@ public class WaitingRoom extends GenericEntity<Long> { @JdbcType(PostgreSQLEnumJdbcType.class) private WaitingStatus status; + @NotNull @LastModifiedDate private Instant modifiedAt; + @Override public Long getId() { return id; @@ -57,4 +61,8 @@ public class WaitingRoom extends GenericEntity<Long> { public void setProcedure(SchoolEntryProcedure procedure) { this.procedure = procedure; } + + public Instant getModifiedAt() { + return modifiedAt; + } } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/specification/SchoolEntryProcedureSpecification.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/specification/SchoolEntryProcedureSpecification.java index f76ac488a3f77c5920352cf44697e350682a4420..22ec01d9a33fa44079bc8f084d4d06844ccd76d0 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/specification/SchoolEntryProcedureSpecification.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/specification/SchoolEntryProcedureSpecification.java @@ -8,17 +8,12 @@ package de.eshg.schoolentry.domain.specification; import de.eshg.lib.appointmentblock.persistence.entity.Appointment_; import de.eshg.lib.procedure.domain.model.ProcedureStatus; import de.eshg.lib.procedure.domain.model.ProcedureType; +import de.eshg.schoolentry.domain.model.Label; +import de.eshg.schoolentry.domain.model.Label_; import de.eshg.schoolentry.domain.model.SchoolEntryProcedure; import de.eshg.schoolentry.domain.model.SchoolEntryProcedure_; import de.eshg.schoolentry.util.ProcedureSortKey; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Expression; -import jakarta.persistence.criteria.JoinType; -import jakarta.persistence.criteria.Order; -import jakarta.persistence.criteria.Path; -import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Root; +import jakarta.persistence.criteria.*; import java.io.Serial; import java.time.Instant; import java.time.Year; @@ -28,7 +23,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.UUID; -import org.apache.poi.ss.formula.functions.T; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.util.Assert; @@ -43,6 +37,7 @@ public class SchoolEntryProcedureSpecification implements Specification<SchoolEn private final Year schoolYearFilter; private final Instant dayOfAppointmentFilter; private final Boolean hasAppointmentFilter; + private final ArrayList<UUID> labelFilter; private final ProcedureSortKey sortKey; private final Sort.Direction sortDirection; @@ -53,6 +48,7 @@ public class SchoolEntryProcedureSpecification implements Specification<SchoolEn Year schoolYearFilter, Instant dayOfAppointmentFilter, Boolean hasAppointmentFilter, + ArrayList<UUID> labelFilter, ProcedureSortKey sortKey, Sort.Direction sortDirection) { this.procedureStatusFilter = procedureStatusFilter; @@ -61,6 +57,7 @@ public class SchoolEntryProcedureSpecification implements Specification<SchoolEn this.schoolYearFilter = schoolYearFilter; this.dayOfAppointmentFilter = dayOfAppointmentFilter; this.hasAppointmentFilter = hasAppointmentFilter; + this.labelFilter = labelFilter; this.sortKey = sortKey; this.sortDirection = sortDirection; } @@ -108,6 +105,17 @@ public class SchoolEntryProcedureSpecification implements Specification<SchoolEn } } + if (labelFilter != null) { + for (UUID labelId : labelFilter) { + Subquery<SchoolEntryProcedure> subquery = query.subquery(SchoolEntryProcedure.class); + Root<SchoolEntryProcedure> subqueryRoot = subquery.correlate(root); + ListJoin<SchoolEntryProcedure, Label> labelJoin = + subqueryRoot.join(SchoolEntryProcedure_.labels); + subquery.where(criteriaBuilder.equal(labelJoin.get(Label_.externalId), labelId)); + conjunctions.add(criteriaBuilder.exists(subquery)); + } + } + Set<Order> orders = new LinkedHashSet<>(); if (!sortKey.isPersonAttribute()) { orders.add(getOrder(root, criteriaBuilder)); diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/specification/WaitingRoomSpecification.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/specification/WaitingRoomSpecification.java new file mode 100644 index 0000000000000000000000000000000000000000..5b54144d7f097697f00749fe48d04af51b2b2e53 --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/domain/specification/WaitingRoomSpecification.java @@ -0,0 +1,113 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.domain.specification; + +import static java.util.Comparator.nullsLast; + +import de.eshg.lib.procedure.domain.model.ProcedureStatus; +import de.eshg.schoolentry.domain.model.SchoolEntryProcedure; +import de.eshg.schoolentry.domain.model.SchoolEntryProcedure_; +import de.eshg.schoolentry.domain.model.WaitingRoom_; +import de.eshg.schoolentry.domain.model.WaitingStatus; +import de.eshg.schoolentry.util.WaitingRoomSortKey; +import jakarta.persistence.criteria.*; +import java.io.Serial; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.util.Assert; + +public class WaitingRoomSpecification implements Specification<SchoolEntryProcedure> { + + @Serial private static final long serialVersionUID = 1L; + + private final WaitingRoomSortKey sortKey; + private final Sort.Direction sortDirection; + + public WaitingRoomSpecification(WaitingRoomSortKey sortKey, Sort.Direction sortDirection) { + this.sortKey = sortKey; + this.sortDirection = sortDirection; + } + + @Override + public Predicate toPredicate( + Root<SchoolEntryProcedure> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) { + List<Predicate> conjunctions = new ArrayList<>(); + conjunctions.add( + criteriaBuilder.equal( + root.get(SchoolEntryProcedure_.procedureStatus), ProcedureStatus.OPEN)); + conjunctions.add( + criteriaBuilder.isNotNull( + root.get(SchoolEntryProcedure_.waitingRoom).get(WaitingRoom_.status))); + conjunctions.add( + criteriaBuilder.not( + root.get(SchoolEntryProcedure_.waitingRoom) + .get(WaitingRoom_.status) + .in(WaitingStatus.DONE, WaitingStatus.CANCELLED))); + + Set<Order> orders = new LinkedHashSet<>(); + if (!sortKey.isPersonAttribute()) { + orders.add(getOrder(root, criteriaBuilder)); + } + orders.add(getFallbackOrder(root, criteriaBuilder)); + + query.orderBy(orders.stream().toList()); + return criteriaBuilder.and(conjunctions.toArray(Predicate[]::new)); + } + + private Order getFallbackOrder(Root<SchoolEntryProcedure> root, CriteriaBuilder criteriaBuilder) { + Expression<?> fallbackOrderExpression = root.get(SchoolEntryProcedure_.id); + return switch (sortDirection) { + case ASC -> criteriaBuilder.asc(fallbackOrderExpression); + case DESC -> criteriaBuilder.desc(fallbackOrderExpression); + }; + } + + private Order getOrder(Root<SchoolEntryProcedure> root, CriteriaBuilder criteriaBuilder) { + Expression<?> expression = + switch (sortKey) { + case ID -> root.get(SchoolEntryProcedure_.id); + case DATE_OF_BIRTH, FIRSTNAME, LASTNAME -> { + Assert.isTrue( + sortKey.isPersonAttribute(), + sortKey + " was expected to be a person attribute but it is not"); + throw new IllegalArgumentException("Unexpected sort key: " + sortKey); + } + case INFO -> + nullsLastString( + root.get(SchoolEntryProcedure_.waitingRoom).get(WaitingRoom_.description), + criteriaBuilder); + case STATUS -> root.get(SchoolEntryProcedure_.waitingRoom).get(WaitingRoom_.status); + case MODIFIED_AT -> + root.get(SchoolEntryProcedure_.waitingRoom).get(WaitingRoom_.modifiedAt); + }; + + return switch (sortDirection) { + case ASC -> criteriaBuilder.asc(expression); + case DESC -> criteriaBuilder.desc(expression); + }; + } + + private Expression<String> nullsLastString(Path<String> instantPath, CriteriaBuilder cb) { + String valueWhenNull = + switch (sortDirection) { + case ASC -> null; + case DESC -> ""; + }; + return nullsLast(instantPath, cb, valueWhenNull); + } + + // This is a workaround because the CriteriaBuilder currently does not support + // generating SQL’s "NULLS LAST" + // It’s supposed to be added in Java Persistence 3.2 / Hibernate 7.0 + private static <T> Expression<T> nullsLast( + Path<T> instantPath, CriteriaBuilder cb, T valueWhenNull) { + return cb.coalesce(instantPath, cb.literal(valueWhenNull)); + } +} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/AnamnesisMapper.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/AnamnesisMapper.java index a10e63805f55545ce88cf06cdfa9ae1a5a289398..55b88c0313153676aa5380c3d8567fbeee8479e6 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/AnamnesisMapper.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/AnamnesisMapper.java @@ -10,6 +10,7 @@ import de.eshg.schoolentry.api.anamnesis.*; import de.eshg.schoolentry.api.citizen.CitizenAnamnesisDto; import de.eshg.schoolentry.api.citizen.CitizenMigrationBackgroundDto; import de.eshg.schoolentry.domain.model.Anamnesis; +import de.eshg.schoolentry.domain.model.BooleanWithUnknown; import de.eshg.schoolentry.domain.model.CountryCode; import jakarta.annotation.Nullable; @@ -27,15 +28,15 @@ public class AnamnesisMapper { anamnesis.getChildLanguageScreening(), anamnesis.getPreliminaryCourse(), new CheckUpsDto( - anamnesis.getU2(), - anamnesis.getU3(), - anamnesis.getU4(), - anamnesis.getU5(), - anamnesis.getU6(), - anamnesis.getU7(), - anamnesis.getU7a(), - anamnesis.getU8(), - anamnesis.getU9()), + mapToDto(anamnesis.getU2()), + mapToDto(anamnesis.getU3()), + mapToDto(anamnesis.getU4()), + mapToDto(anamnesis.getU5()), + mapToDto(anamnesis.getU6()), + mapToDto(anamnesis.getU7()), + mapToDto(anamnesis.getU7a()), + mapToDto(anamnesis.getU8()), + mapToDto(anamnesis.getU9())), new PromotionBeforeSchoolEntryDto( anamnesis.getEarlySupport(), anamnesis.getIntegrationPlace(), @@ -99,6 +100,15 @@ public class AnamnesisMapper { return CountryCodeDto.valueOf(nationalityChild.name()); } + private static BooleanWithUnknownDto mapToDto(BooleanWithUnknown value) { + return switch (value) { + case null -> null; + case TRUE -> BooleanWithUnknownDto.TRUE; + case FALSE -> BooleanWithUnknownDto.FALSE; + case UNKNOWN -> BooleanWithUnknownDto.UNKNOWN; + }; + } + public static Anamnesis mapToDomain(AnamnesisDto dto) { if (dto == null) { return null; @@ -130,15 +140,15 @@ public class AnamnesisMapper { anamnesis.setOtherInterests(dto.interestsAndSportsInfo().otherInterests()); anamnesis.setCanSwim(dto.interestsAndSportsInfo().canSwim()); anamnesis.setHasSeahorseBadge(dto.interestsAndSportsInfo().hasSeahorseBadge()); - anamnesis.setU2(dto.checkUps().u2()); - anamnesis.setU3(dto.checkUps().u3()); - anamnesis.setU4(dto.checkUps().u4()); - anamnesis.setU5(dto.checkUps().u5()); - anamnesis.setU6(dto.checkUps().u6()); - anamnesis.setU7(dto.checkUps().u7()); - anamnesis.setU7a(dto.checkUps().u7a()); - anamnesis.setU8(dto.checkUps().u8()); - anamnesis.setU9(dto.checkUps().u9()); + anamnesis.setU2(mapToDomain(dto.checkUps().u2())); + anamnesis.setU3(mapToDomain(dto.checkUps().u3())); + anamnesis.setU4(mapToDomain(dto.checkUps().u4())); + anamnesis.setU5(mapToDomain(dto.checkUps().u5())); + anamnesis.setU6(mapToDomain(dto.checkUps().u6())); + anamnesis.setU7(mapToDomain(dto.checkUps().u7())); + anamnesis.setU7a(mapToDomain(dto.checkUps().u7a())); + anamnesis.setU8(mapToDomain(dto.checkUps().u8())); + anamnesis.setU9(mapToDomain(dto.checkUps().u9())); anamnesis.setEarlySupport(dto.promotionBeforeSchoolEntry().earlySupport()); anamnesis.setIntegrationPlace(dto.promotionBeforeSchoolEntry().integrationPlace()); anamnesis.setErgotherapy(dto.promotionBeforeSchoolEntry().ergotherapy()); @@ -174,6 +184,15 @@ public class AnamnesisMapper { return anamnesis; } + private static BooleanWithUnknown mapToDomain(BooleanWithUnknownDto value) { + return switch (value) { + case null -> null; + case TRUE -> BooleanWithUnknown.TRUE; + case FALSE -> BooleanWithUnknown.FALSE; + case UNKNOWN -> BooleanWithUnknown.UNKNOWN; + }; + } + public static Anamnesis mapCitizenAnamnesisToDomain(CitizenAnamnesisDto citizenAnamnesisDto) { Anamnesis anamnesis = new Anamnesis(); anamnesis.setNationalityChild( diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/VaccinationStatusMapper.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/VaccinationStatusMapper.java index 575d9436b6d9d26649ea23ccdc8943741f4ca2cc..d50aecfbd0c02b8a38d45e497553b4ca45097608 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/VaccinationStatusMapper.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/VaccinationStatusMapper.java @@ -6,6 +6,7 @@ package de.eshg.schoolentry.mapper; import de.eshg.schoolentry.api.*; +import de.eshg.schoolentry.domain.model.BooleanWithUnknown; import de.eshg.schoolentry.domain.model.OtherVaccination; import de.eshg.schoolentry.domain.model.VaccinationSchemeValue; import de.eshg.schoolentry.domain.model.VaccinationStatus; @@ -39,7 +40,7 @@ public final class VaccinationStatusMapper { vaccinationStatus.getHepatitisA(), mapToDto(vaccinationStatus.getOtherVaccinations()), vaccinationStatus.getVaccinationPassPresented(), - vaccinationStatus.getPerkombiHbv()); + mapToDto(vaccinationStatus.getPerkombiHbv())); } private static List<OtherVaccinationDto> mapToDto(List<OtherVaccination> otherVaccinations) { @@ -75,7 +76,7 @@ public final class VaccinationStatusMapper { vaccinationStatus.setHepatitisA(dto.hepatitisA()); vaccinationStatus.setOtherVaccinations(mapToDomain(dto.otherVaccinations())); vaccinationStatus.setVaccinationPassPresented(dto.vaccinationPassPresented()); - vaccinationStatus.setPerkombiHbv(dto.perkombiHbv()); + vaccinationStatus.setPerkombiHbv(mapToDomain(dto.perkombiHbv())); return vaccinationStatus; } @@ -104,4 +105,22 @@ public final class VaccinationStatusMapper { case UNKNOWN -> VaccinationSchemeValue.UNKNOWN; }; } + + private static BooleanWithUnknownDto mapToDto(BooleanWithUnknown value) { + return switch (value) { + case null -> null; + case TRUE -> BooleanWithUnknownDto.TRUE; + case FALSE -> BooleanWithUnknownDto.FALSE; + case UNKNOWN -> BooleanWithUnknownDto.UNKNOWN; + }; + } + + private static BooleanWithUnknown mapToDomain(BooleanWithUnknownDto value) { + return switch (value) { + case null -> null; + case TRUE -> BooleanWithUnknown.TRUE; + case FALSE -> BooleanWithUnknown.FALSE; + case UNKNOWN -> BooleanWithUnknown.UNKNOWN; + }; + } } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/WaitingRoomMapper.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/WaitingRoomMapper.java index 97b61f39d364e40542bd20d5a8aa8f10810a0a5c..aefb510e46e1f41d027b75c91e19271ecbd761ed 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/WaitingRoomMapper.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/mapper/WaitingRoomMapper.java @@ -5,14 +5,30 @@ package de.eshg.schoolentry.mapper; -import de.eshg.schoolentry.api.WaitingRoomDto; -import de.eshg.schoolentry.api.WaitingStatusDto; +import de.eshg.base.SortDirection; +import de.eshg.schoolentry.WaitingRoomPageSpec; +import de.eshg.schoolentry.api.*; +import de.eshg.schoolentry.business.model.WaitingRoomProcedureData; import de.eshg.schoolentry.domain.model.WaitingRoom; import de.eshg.schoolentry.domain.model.WaitingStatus; +import org.springframework.data.domain.Sort; public final class WaitingRoomMapper { private WaitingRoomMapper() {} + public static WaitingRoomProcedureDto mapWaitingRoomProcedureToDto( + WaitingRoomProcedureData procedureData) { + if (procedureData == null) { + return null; + } + + return new WaitingRoomProcedureDto( + procedureData.externalId(), + PersonMapper.mapChildToDto(procedureData.child()), + mapToDto(procedureData.waitingRoom()), + procedureData.modifiedAt()); + } + public static WaitingRoomDto mapToDto(WaitingRoom waitingRoom) { if (waitingRoom == null) { return null; @@ -62,4 +78,32 @@ public final class WaitingRoomMapper { case CANCELLED -> WaitingStatus.CANCELLED; }; } + + public static WaitingRoomPageSpec mapToPageSpec( + int page, int pageSize, WaitingRoomSortKey sortField, SortDirection direction) { + return new WaitingRoomPageSpec( + page, pageSize, mapSortField(sortField), mapDirection(direction)); + } + + private static de.eshg.schoolentry.util.WaitingRoomSortKey mapSortField( + WaitingRoomSortKey sortKey) { + return switch (sortKey) { + case null -> de.eshg.schoolentry.util.WaitingRoomSortKey.ID; + case ID -> de.eshg.schoolentry.util.WaitingRoomSortKey.ID; + case DATE_OF_BIRTH -> de.eshg.schoolentry.util.WaitingRoomSortKey.DATE_OF_BIRTH; + case FIRSTNAME -> de.eshg.schoolentry.util.WaitingRoomSortKey.FIRSTNAME; + case LASTNAME -> de.eshg.schoolentry.util.WaitingRoomSortKey.LASTNAME; + case INFO -> de.eshg.schoolentry.util.WaitingRoomSortKey.INFO; + case STATUS -> de.eshg.schoolentry.util.WaitingRoomSortKey.STATUS; + case MODIFIED_AT -> de.eshg.schoolentry.util.WaitingRoomSortKey.MODIFIED_AT; + }; + } + + public static Sort.Direction mapDirection(SortDirection sortDirection) { + return switch (sortDirection) { + case null -> Sort.Direction.ASC; + case ASC -> Sort.Direction.ASC; + case DESC -> Sort.Direction.DESC; + }; + } } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/AbstractGenerator.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/AbstractGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..4f8cd1eb1e28ba651617c29d82ee1f154a085937 --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/AbstractGenerator.java @@ -0,0 +1,73 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.pdf; + +import de.eshg.base.address.DomesticAddressDto; +import de.eshg.base.address.PostboxAddressDto; +import de.eshg.base.client.ContactClient; +import de.eshg.base.contact.api.ContactDto; +import de.eshg.base.contact.api.InstitutionContactDto; +import de.eshg.base.department.GetDepartmentInfoResponse; +import de.eshg.lib.document.generator.department.DepartmentClient; +import java.util.UUID; +import org.springframework.util.Assert; + +public abstract class AbstractGenerator { + + protected final DepartmentClient departmentClient; + protected final ContactClient contactClient; + + public AbstractGenerator(DepartmentClient departmentClient, ContactClient contactClient) { + this.departmentClient = departmentClient; + this.contactClient = contactClient; + } + + public Address getDepartmentAddress() { + GetDepartmentInfoResponse departmentInfo = departmentClient.getDepartmentInfo(); + return new Address( + departmentInfo.name(), + departmentInfo.street() + " " + departmentInfo.houseNumber(), + departmentInfo.postalCode(), + departmentInfo.city(), + departmentInfo.phoneNumber(), + departmentInfo.homepage(), + null, + departmentInfo.email()); + } + + public Address getAddressOfInstitution(UUID institutionLocationId) { + ContactDto institution = contactClient.getContact(institutionLocationId); + + Assert.notNull(institution, () -> "Institution contact must not be null"); + Assert.isInstanceOf( + InstitutionContactDto.class, + institution, + () -> "Function must only be used to retrieve institution contacts"); + + return switch (institution.contactAddress()) { + case DomesticAddressDto domesticAddress -> + new Address( + institution.name(), + domesticAddress.street() + " " + domesticAddress.houseNumber(), + domesticAddress.postalCode(), + domesticAddress.city(), + null, + null, + domesticAddress.addressAddition(), + null); + case PostboxAddressDto postboxAddress -> + new Address( + postboxAddress.postbox(), + postboxAddress.differentName(), + postboxAddress.postalCode(), + postboxAddress.city(), + null, + null, + null, + null); + }; + } +} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/invitation/InvitationExamination.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/invitation/InvitationExamination.java index 0c4ba71f0d38444852d13c2ecbbf32a04f6bcb34..997343f726ac6b4dcc2d3a70738e725a5ae8eeb6 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/invitation/InvitationExamination.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/invitation/InvitationExamination.java @@ -5,5 +5,11 @@ package de.eshg.schoolentry.pdf.invitation; +import de.eshg.schoolentry.pdf.Address; + public record InvitationExamination( - String executionDate, String executionTime, String qrCode, String accessCode) {} + String executionDate, + String executionTime, + String qrCode, + String accessCode, + Address executionLocation) {} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/invitation/InvitationGenerator.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/invitation/InvitationGenerator.java index ded9433dfe09c67b078f013375fb3e199ff0a83d..74a69280bf81170e6407e92594cded87ac0d51ea 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/invitation/InvitationGenerator.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/invitation/InvitationGenerator.java @@ -8,7 +8,9 @@ package de.eshg.schoolentry.pdf.invitation; import de.eshg.base.address.AddressDto; import de.eshg.base.address.DomesticAddressDto; import de.eshg.base.address.PostboxAddressDto; -import de.eshg.base.department.GetDepartmentInfoResponse; +import de.eshg.base.client.ContactClient; +import de.eshg.lib.appointmentblock.LocationSelectionMode; +import de.eshg.lib.appointmentblock.spring.AppointmentBlockProperties; import de.eshg.lib.document.generator.DocumentGenerator; import de.eshg.lib.document.generator.department.DepartmentClient; import de.eshg.lib.document.generator.department.DepartmentLogo; @@ -17,6 +19,7 @@ import de.eshg.lib.procedure.domain.model.Pdf; import de.eshg.lib.procedure.domain.model.PdfMetaData; import de.eshg.lib.procedure.file.FileFactory; import de.eshg.schoolentry.business.model.ChildData; +import de.eshg.schoolentry.pdf.AbstractGenerator; import de.eshg.schoolentry.pdf.Address; import de.eshg.schoolentry.pdf.QrCodeGenerator; import de.eshg.schoolentry.pdf.ReportGeneratorConstants; @@ -27,6 +30,7 @@ import java.time.Instant; import java.time.ZonedDateTime; import java.util.Base64; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; import org.apache.commons.collections4.ListUtils; import org.apache.commons.lang3.StringUtils; @@ -38,27 +42,30 @@ import org.springframework.util.Assert; import org.springframework.web.util.UriComponentsBuilder; @Component -public class InvitationGenerator { +public class InvitationGenerator extends AbstractGenerator { static final String INVITATION_TEMPLATE = "/templates/invitation.ftlx"; private static final String CITIZEN_PORTAL_LANDING_PAGE_PATH = "esu"; private final ClassPathResource invitationTemplate; - private final DepartmentClient departmentClient; private final String citizenPortalUrl; private final DocumentGenerator documentGenerator; private final Clock clock; + private final AppointmentBlockProperties appointmentBlockProperties; public InvitationGenerator( @Value(INVITATION_TEMPLATE) ClassPathResource invitationTemplate, DepartmentClient departmentClient, @Value("${eshg.citizen-portal.reverse-proxy.url}") String citizenPortalUrl, DocumentGenerator documentGenerator, - Clock clock) { + Clock clock, + AppointmentBlockProperties appointmentBlockProperties, + ContactClient contactClient) { + super(departmentClient, contactClient); + this.appointmentBlockProperties = appointmentBlockProperties; Assert.isTrue(invitationTemplate.exists(), () -> invitationTemplate + " does not exist"); this.invitationTemplate = invitationTemplate; - this.departmentClient = departmentClient; this.citizenPortalUrl = citizenPortalUrl; this.documentGenerator = documentGenerator; this.clock = clock; @@ -72,14 +79,22 @@ public class InvitationGenerator { } @VisibleForTesting - InvitationData buildInvitationData(String accessCode, ChildData child, Instant appointmentStart) { + InvitationData buildInvitationData( + String accessCode, ChildData child, Instant appointmentStart, UUID locationId) { String url = buildQrCodeUrl(accessCode); String qrCode = Base64.getEncoder() .encodeToString(QrCodeGenerator.createQrCode(url).getBytes(StandardCharsets.UTF_8)); - Address departmentAddress = fetchDepartmentAddress(); + Address departmentAddress = getDepartmentAddress(); DepartmentLogo departmentLogo = departmentClient.getDepartmentLogo(); + Address examinationExecutionLocation; + if (appointmentBlockProperties.getLocationSelectionMode() != LocationSelectionMode.NONE + && locationId != null) { + examinationExecutionLocation = getAddressOfInstitution(locationId); + } else { + examinationExecutionLocation = departmentAddress; + } AddressDto address = child.address(); Address childAddress = @@ -115,7 +130,8 @@ public class InvitationGenerator { zonedAppointmentStart.format(ReportGeneratorConstants.DATE_FORMAT_DE), zonedAppointmentStart.format(ReportGeneratorConstants.TIME_FORMAT_DE), qrCode, - formatAccessCode(accessCode)); + formatAccessCode(accessCode), + examinationExecutionLocation); InvitationInfo invitationInfo = new InvitationInfo( "Frankfurt am Main", @@ -131,19 +147,6 @@ public class InvitationGenerator { "#EBEBEB"); } - private Address fetchDepartmentAddress() { - GetDepartmentInfoResponse departmentInfo = departmentClient.getDepartmentInfo(); - return new Address( - departmentInfo.name(), - departmentInfo.street() + " " + departmentInfo.houseNumber(), - departmentInfo.postalCode(), - departmentInfo.city(), - departmentInfo.phoneNumber(), - departmentInfo.homepage(), - null, - departmentInfo.email()); - } - private static String concat(String... strings) { return String.join(" ", strings); } @@ -166,8 +169,9 @@ public class InvitationGenerator { return StringUtils.substringAfter(landingPageUrlWithoutScheme, "//"); } - public Pdf generateInvitation(String accessCode, ChildData childData, Instant start) { - InvitationData invitationData = buildInvitationData(accessCode, childData, start); + public Pdf generateInvitation( + String accessCode, ChildData childData, Instant start, UUID locationId) { + InvitationData invitationData = buildInvitationData(accessCode, childData, start, locationId); return generateInvitation(invitationData); } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/medicalreport/MedicalReportGenerator.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/medicalreport/MedicalReportGenerator.java index 1ab90b61da37e7afdabfef8b143f4b9e9edf8b3d..ef57085ef92a4d2b0f6ef61bc30bb00041381c38 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/medicalreport/MedicalReportGenerator.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/medicalreport/MedicalReportGenerator.java @@ -5,7 +5,7 @@ package de.eshg.schoolentry.pdf.medicalreport; -import de.eshg.base.department.GetDepartmentInfoResponse; +import de.eshg.base.client.ContactClient; import de.eshg.lib.document.generator.DocumentGenerator; import de.eshg.lib.document.generator.department.DepartmentClient; import de.eshg.lib.document.generator.department.DepartmentLogo; @@ -15,6 +15,7 @@ import de.eshg.lib.procedure.domain.model.PdfMetaData; import de.eshg.lib.procedure.file.FileFactory; import de.eshg.schoolentry.api.CreateMedicalReportRequest; import de.eshg.schoolentry.business.model.ChildDetailsData; +import de.eshg.schoolentry.pdf.AbstractGenerator; import de.eshg.schoolentry.pdf.Address; import de.eshg.schoolentry.pdf.ReportGeneratorConstants; import java.io.ByteArrayOutputStream; @@ -27,12 +28,11 @@ import org.springframework.stereotype.Component; import org.springframework.util.Assert; @Component -public class MedicalReportGenerator { +public class MedicalReportGenerator extends AbstractGenerator { static final String MEDICAL_REPORT_TEMPLATE = "/templates/medicalreport.ftlx"; private final ClassPathResource medicalReportTemplate; - private final DepartmentClient departmentClient; private final DocumentGenerator documentGenerator; private final Clock clock; @@ -40,10 +40,11 @@ public class MedicalReportGenerator { @Value(MEDICAL_REPORT_TEMPLATE) ClassPathResource medicalReportTemplate, DepartmentClient departmentClient, DocumentGenerator documentGenerator, - Clock clock) { + Clock clock, + ContactClient contactClient) { + super(departmentClient, contactClient); Assert.isTrue(medicalReportTemplate.exists(), () -> medicalReportTemplate + " does not exist"); this.medicalReportTemplate = medicalReportTemplate; - this.departmentClient = departmentClient; this.documentGenerator = documentGenerator; this.clock = clock; } @@ -51,7 +52,7 @@ public class MedicalReportGenerator { @VisibleForTesting MedicalReportData buildMedicalReportData( ChildDetailsData child, CreateMedicalReportRequest request) { - Address departmentAddress = fetchDepartmentAddress(); + Address departmentAddress = getDepartmentAddress(); DepartmentLogo departmentLogo = departmentClient.getDepartmentLogo(); MedicalReportChild medicalReportChild = @@ -62,19 +63,6 @@ public class MedicalReportGenerator { departmentLogo, departmentAddress, medicalReportChild, request.remark(), request.isVisio()); } - private Address fetchDepartmentAddress() { - GetDepartmentInfoResponse departmentInfo = departmentClient.getDepartmentInfo(); - return new Address( - departmentInfo.name(), - departmentInfo.street() + " " + departmentInfo.houseNumber(), - departmentInfo.postalCode(), - departmentInfo.city(), - departmentInfo.phoneNumber(), - departmentInfo.homepage(), - null, - departmentInfo.email()); - } - private static String concat(String... strings) { return String.join(" ", strings); } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/schoolinfoletter/SchoolInfoLetterGenerator.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/schoolinfoletter/SchoolInfoLetterGenerator.java index c5def8a103b1ed96e466f8a767adff381a681878..dcfdf6c00ccb4c25e789c33acfc4273b69de219e 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/schoolinfoletter/SchoolInfoLetterGenerator.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/pdf/schoolinfoletter/SchoolInfoLetterGenerator.java @@ -5,11 +5,7 @@ package de.eshg.schoolentry.pdf.schoolinfoletter; -import de.eshg.base.address.DomesticAddressDto; -import de.eshg.base.address.PostboxAddressDto; import de.eshg.base.client.ContactClient; -import de.eshg.base.contact.api.ContactDto; -import de.eshg.base.department.GetDepartmentInfoResponse; import de.eshg.lib.document.generator.DocumentGenerator; import de.eshg.lib.document.generator.department.DepartmentClient; import de.eshg.lib.document.generator.department.DepartmentLogo; @@ -20,6 +16,7 @@ import de.eshg.lib.procedure.file.FileFactory; import de.eshg.schoolentry.api.CreateSchoolInfoLetterRequest; import de.eshg.schoolentry.business.model.ProcedureDetailsData; import de.eshg.schoolentry.domain.model.SchoolEntryProcedure; +import de.eshg.schoolentry.pdf.AbstractGenerator; import de.eshg.schoolentry.pdf.Address; import de.eshg.schoolentry.pdf.ReportGeneratorConstants; import de.eshg.schoolentry.pdf.schoolinfoletter.model.*; @@ -28,7 +25,6 @@ import java.time.Clock; import java.time.LocalDate; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; -import java.util.UUID; import org.jetbrains.annotations.VisibleForTesting; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; @@ -36,13 +32,11 @@ import org.springframework.stereotype.Component; import org.springframework.util.Assert; @Component -public class SchoolInfoLetterGenerator { +public class SchoolInfoLetterGenerator extends AbstractGenerator { static final String SCHOOL_INFO_LETTER_TEMPLATE = "/templates/school_info_letter.ftlh"; private final ClassPathResource schoolInfoLetterTemplate; - private final DepartmentClient departmentClient; - private final ContactClient contactClient; private final SchoolInfoLetterExaminationMapper schoolInfoLetterExaminationMapper; private final DocumentGenerator documentGenerator; private final Clock clock; @@ -54,12 +48,11 @@ public class SchoolInfoLetterGenerator { DocumentGenerator documentGenerator, Clock clock, SchoolInfoLetterExaminationMapper schoolInfoLetterExaminationMapper) { - this.contactClient = contactClient; + super(departmentClient, contactClient); this.schoolInfoLetterExaminationMapper = schoolInfoLetterExaminationMapper; Assert.isTrue( schoolInfoLetterTemplate.exists(), () -> schoolInfoLetterTemplate + " does not exist"); this.schoolInfoLetterTemplate = schoolInfoLetterTemplate; - this.departmentClient = departmentClient; this.documentGenerator = documentGenerator; this.clock = clock; } @@ -89,8 +82,8 @@ public class SchoolInfoLetterGenerator { SchoolEntryProcedure procedure, ProcedureDetailsData procedureDetailsData, CreateSchoolInfoLetterRequest request) { - Address departmentAddress = fetchDepartmentAddress(); - Address schoolAddress = fetchSchoolAddress(procedureDetailsData.school().id()); + Address departmentAddress = getDepartmentAddress(); + Address schoolAddress = getAddressOfInstitution(procedureDetailsData.school().id()); DepartmentLogo departmentLogo = departmentClient.getDepartmentLogo(); return new SchoolInfoLetterData( LocalDate.now(clock).format(DateTimeFormatter.ofPattern("dd.MM.yyyy")), @@ -99,46 +92,4 @@ public class SchoolInfoLetterGenerator { schoolAddress, schoolInfoLetterExaminationMapper.mapToData(procedure, procedureDetailsData, request)); } - - private Address fetchDepartmentAddress() { - GetDepartmentInfoResponse departmentInfo = departmentClient.getDepartmentInfo(); - return new Address( - departmentInfo.name(), - departmentInfo.street() + " " + departmentInfo.houseNumber(), - departmentInfo.postalCode(), - departmentInfo.city(), - departmentInfo.phoneNumber(), - departmentInfo.homepage(), - null, - departmentInfo.email()); - } - - private Address fetchSchoolAddress(UUID schoolId) { - ContactDto school = contactClient.getContact(schoolId); - - Assert.notNull(school, () -> "School not found"); - - return switch (school.contactAddress()) { - case DomesticAddressDto domesticAddress -> - new Address( - school.name(), - domesticAddress.street() + " " + domesticAddress.houseNumber(), - domesticAddress.postalCode(), - domesticAddress.city(), - null, - null, - domesticAddress.addressAddition(), - null); - case PostboxAddressDto postboxAddress -> - new Address( - postboxAddress.postbox(), - postboxAddress.differentName(), - postboxAddress.postalCode(), - postboxAddress.city(), - null, - null, - null, - null); - }; - } } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/EsuAttributes.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/EsuAttributes.java index 20c34186e900dac98bb0b6071a30a87789f41bb1..4e4b02fe30edf221b1f9a41b292cf1931a95093a 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/EsuAttributes.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/EsuAttributes.java @@ -99,23 +99,77 @@ public enum EsuAttributes implements AttributeInfo { ATTRIBUTE_CATEGORY_ANAMNESIS, false), - U2E("U2", "U2E", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_ANAMNESIS, true), + U2E( + "U2", + "U2E", + true, + convertToValueOptions(BooleanWithUnknown.values()), + ATTRIBUTE_CATEGORY_ANAMNESIS, + true), - U3E("U3", "U3E", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_ANAMNESIS, true), + U3E( + "U3", + "U3E", + true, + convertToValueOptions(BooleanWithUnknown.values()), + ATTRIBUTE_CATEGORY_ANAMNESIS, + true), - U4E("U4", "U4E", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_ANAMNESIS, true), + U4E( + "U4", + "U4E", + true, + convertToValueOptions(BooleanWithUnknown.values()), + ATTRIBUTE_CATEGORY_ANAMNESIS, + true), - U5E("U5", "U5E", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_ANAMNESIS, true), + U5E( + "U5", + "U5E", + true, + convertToValueOptions(BooleanWithUnknown.values()), + ATTRIBUTE_CATEGORY_ANAMNESIS, + true), - U6E("U6", "U6E", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_ANAMNESIS, true), + U6E( + "U6", + "U6E", + true, + convertToValueOptions(BooleanWithUnknown.values()), + ATTRIBUTE_CATEGORY_ANAMNESIS, + true), - U7E("U7", "U7E", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_ANAMNESIS, true), + U7E( + "U7", + "U7E", + true, + convertToValueOptions(BooleanWithUnknown.values()), + ATTRIBUTE_CATEGORY_ANAMNESIS, + true), - U7A("U7a", "U7A", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_ANAMNESIS, true), + U7A( + "U7a", + "U7A", + true, + convertToValueOptions(BooleanWithUnknown.values()), + ATTRIBUTE_CATEGORY_ANAMNESIS, + true), - U8E("U8", "U8E", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_ANAMNESIS, true), + U8E( + "U8", + "U8E", + true, + convertToValueOptions(BooleanWithUnknown.values()), + ATTRIBUTE_CATEGORY_ANAMNESIS, + true), - U9E("U9", "U9E", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_ANAMNESIS, true), + U9E( + "U9", + "U9E", + true, + convertToValueOptions(BooleanWithUnknown.values()), + ATTRIBUTE_CATEGORY_ANAMNESIS, + true), FF("Frühförderung", "FF", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_ANAMNESIS, true), @@ -331,7 +385,12 @@ public enum EsuAttributes implements AttributeInfo { true), PERKOMBIHBV( - "PerkombiHBV", "PerkombiHBV", true, ValueType.BOOLEAN, ATTRIBUTE_CATEGORY_VACCINATION, true), + "PerkombiHBV", + "PerkombiHBV", + true, + convertToValueOptions(BooleanWithUnknown.values()), + ATTRIBUTE_CATEGORY_VACCINATION, + true), HBV( "Impfungen Hepatitis B Summe", diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/SchoolEntryStatisticsService.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/SchoolEntryStatisticsService.java index 28d0f8728cbcfb084789ddad70214d04d302c0a7..015ba6b5b5ce84d5eb9a67feba1b896f6b059815 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/SchoolEntryStatisticsService.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/SchoolEntryStatisticsService.java @@ -16,6 +16,7 @@ import de.eshg.schoolentry.api.CountryCodeDto; import de.eshg.schoolentry.domain.model.*; import de.eshg.schoolentry.domain.repository.SchoolEntryProcedureRepository; import de.eshg.schoolentry.statistics.options.*; +import de.eshg.schoolentry.statistics.options.BooleanWithUnknown; import de.eshg.schoolentry.statistics.options.DoctorLetterValue; import jakarta.annotation.Nullable; import java.time.*; @@ -72,15 +73,15 @@ public class SchoolEntryStatisticsService extends AbstractStatisticsService<Scho case GG -> getAnamnesisAttribute(procedure, Anamnesis::getBirthWeight); case SSW_DAUER -> getAnamnesisAttribute(procedure, Anamnesis::getGestationalAge); case KIH -> getAnamnesisAttribute(procedure, Anamnesis::getNumberOfSiblings); - case U2E -> getAnamnesisAttribute(procedure, Anamnesis::getU2); - case U3E -> getAnamnesisAttribute(procedure, Anamnesis::getU3); - case U4E -> getAnamnesisAttribute(procedure, Anamnesis::getU4); - case U5E -> getAnamnesisAttribute(procedure, Anamnesis::getU5); - case U6E -> getAnamnesisAttribute(procedure, Anamnesis::getU6); - case U7A -> getAnamnesisAttribute(procedure, Anamnesis::getU7a); - case U7E -> getAnamnesisAttribute(procedure, Anamnesis::getU7); - case U8E -> getAnamnesisAttribute(procedure, Anamnesis::getU8); - case U9E -> getAnamnesisAttribute(procedure, Anamnesis::getU9); + case U2E -> getAnamnesisCheckUpsAttribute(procedure, Anamnesis::getU2); + case U3E -> getAnamnesisCheckUpsAttribute(procedure, Anamnesis::getU3); + case U4E -> getAnamnesisCheckUpsAttribute(procedure, Anamnesis::getU4); + case U5E -> getAnamnesisCheckUpsAttribute(procedure, Anamnesis::getU5); + case U6E -> getAnamnesisCheckUpsAttribute(procedure, Anamnesis::getU6); + case U7A -> getAnamnesisCheckUpsAttribute(procedure, Anamnesis::getU7a); + case U7E -> getAnamnesisCheckUpsAttribute(procedure, Anamnesis::getU7); + case U8E -> getAnamnesisCheckUpsAttribute(procedure, Anamnesis::getU8); + case U9E -> getAnamnesisCheckUpsAttribute(procedure, Anamnesis::getU9); case FF -> getAnamnesisAttribute(procedure, Anamnesis::getEarlySupport); case IP -> getAnamnesisAttribute(procedure, Anamnesis::getIntegrationPlace); case ERGO -> getAnamnesisAttribute(procedure, Anamnesis::getErgotherapy); @@ -488,7 +489,7 @@ public class SchoolEntryStatisticsService extends AbstractStatisticsService<Scho LocalDate inDaycareSince = procedure.getAnamnesis().getInDaycareSince(); if (inDaycareSince == null) { - return Daycare.NO.getValue(); + return Daycare.UNKNOWN.getValue(); } else { return getDaycareValue(appointmentDate, inDaycareSince); } @@ -587,12 +588,12 @@ public class SchoolEntryStatisticsService extends AbstractStatisticsService<Scho vaccinationStatus.getVaccinationScheme()); } - private @Nullable Boolean getPerkombiHbv(VaccinationStatus vaccinationStatus) { + private @Nullable String getPerkombiHbv(VaccinationStatus vaccinationStatus) { if (vaccinationStatus == null) { return null; } - return vaccinationStatus.getPerkombiHbv(); + return BooleanWithUnknown.convertToValue(vaccinationStatus.getPerkombiHbv()); } private <T> @Nullable T getAnamnesisAttribute( @@ -604,6 +605,16 @@ public class SchoolEntryStatisticsService extends AbstractStatisticsService<Scho return anamnesisGetter.apply(anamnesis); } + private @Nullable String getAnamnesisCheckUpsAttribute( + SchoolEntryProcedure procedure, + Function<Anamnesis, de.eshg.schoolentry.domain.model.BooleanWithUnknown> anamnesisGetter) { + Anamnesis anamnesis = procedure.getAnamnesis(); + if (anamnesis == null) { + return null; + } + return BooleanWithUnknown.convertToValue(anamnesisGetter.apply(anamnesis)); + } + private @Nullable String getCountryCode( SchoolEntryProcedure procedure, Function<Anamnesis, CountryCode> anamnesisGetter) { Anamnesis anamnesis = procedure.getAnamnesis(); @@ -628,9 +639,12 @@ public class SchoolEntryStatisticsService extends AbstractStatisticsService<Scho private @Nullable String getInGermanySinceAttribute(SchoolEntryProcedure procedure) { Anamnesis anamnesis = procedure.getAnamnesis(); - if (anamnesis == null || anamnesis.getInGermanySince() == null) { + if (anamnesis == null) { return null; } + if (anamnesis.getInGermanySince() == null) { + return ""; + } return anamnesis.getInGermanySince().format(DATE_FORMAT); } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/BooleanWithUnknown.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/BooleanWithUnknown.java new file mode 100644 index 0000000000000000000000000000000000000000..c2bf79b4e20eda84e6e0107279aa8ce6740ae593 --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/BooleanWithUnknown.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.statistics.options; + +import de.eshg.lib.statistics.util.ConvertibleToValueOptions; + +public enum BooleanWithUnknown implements ConvertibleToValueOptions { + TRUE("Ja", "Ja"), + FALSE("Nein", "Nein"), + UNKNOWN("Unbekannt", "Unbekannt"); + + private final String value; + private final String meaning; + + BooleanWithUnknown(String value, String meaning) { + this.value = value; + this.meaning = meaning; + } + + public static String convertToValue(de.eshg.schoolentry.domain.model.BooleanWithUnknown value) { + return switch (value) { + case null -> null; + case TRUE -> BooleanWithUnknown.TRUE.getValue(); + case FALSE -> BooleanWithUnknown.FALSE.getValue(); + case UNKNOWN -> BooleanWithUnknown.UNKNOWN.getValue(); + }; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String getMeaning() { + return meaning; + } + + @Override + public boolean isUnknownValue() { + return this.equals(UNKNOWN); + } +} diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/Daycare.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/Daycare.java index 739918174a692b9bad6553a23ddca590a4155492..0d72741659e7fad84c7ffb4a51dfbd57d0d9d98f 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/Daycare.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/Daycare.java @@ -11,7 +11,8 @@ public enum Daycare implements ConvertibleToValueOptions { NO("0", "kein Besuch"), MONTH_18("1", "< 18 Monate"), MONTH_18_TO_YEARS_3("2", "18 Monate - 3 Jahre"), - YEARS_3("3", "> 3 Jahre"); + YEARS_3("3", "> 3 Jahre"), + UNKNOWN("9", "unbekannt"); private final String value; private final String meaning; @@ -30,4 +31,9 @@ public enum Daycare implements ConvertibleToValueOptions { public String getMeaning() { return meaning; } + + @Override + public boolean isUnknownValue() { + return this.equals(UNKNOWN); + } } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/VaccinationScheme.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/VaccinationScheme.java index 7511db7e2ac9885d7675b59413723ca8c59fb94e..8b2d773980b657f604f2a616e83bd09a5733e2e8 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/VaccinationScheme.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/statistics/options/VaccinationScheme.java @@ -11,7 +11,7 @@ import de.eshg.schoolentry.domain.model.VaccinationSchemeValue; public enum VaccinationScheme implements ConvertibleToValueOptions { SCHEME_2_PLUS_1("2", "2+1"), SCHEME_3_PLUS_1_3("3", "3+1"), - UNKNOWN("9", " unbekannt"); + UNKNOWN("9", "unbekannt"); private final String value; diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/testhelper/SchoolEntryProceduresPopulator.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/testhelper/SchoolEntryProceduresPopulator.java index 4e6c894860764145b6ec0d399aef0b39773bbbb2..1a83d4f4f9af414a45db73dbca003b149b8831b3 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/testhelper/SchoolEntryProceduresPopulator.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/testhelper/SchoolEntryProceduresPopulator.java @@ -535,15 +535,15 @@ public class SchoolEntryProceduresPopulator extends BasePopulator<CreateProcedur private static CheckUpsDto randomCheckUpsDto(Faker faker) { return new CheckUpsDto( - faker.bool().bool(), - faker.bool().bool(), - faker.bool().bool(), - faker.bool().bool(), - faker.bool().bool(), - faker.bool().bool(), - faker.bool().bool(), - faker.bool().bool(), - faker.bool().bool()); + randomBooleanWithUnknownSchoolEntry(faker), + randomBooleanWithUnknownSchoolEntry(faker), + randomBooleanWithUnknownSchoolEntry(faker), + randomBooleanWithUnknownSchoolEntry(faker), + randomBooleanWithUnknownSchoolEntry(faker), + randomBooleanWithUnknownSchoolEntry(faker), + randomBooleanWithUnknownSchoolEntry(faker), + randomBooleanWithUnknownSchoolEntry(faker), + randomBooleanWithUnknownSchoolEntry(faker)); } private static PromotionBeforeSchoolEntryDto randomPromotionBeforeSchoolEntryDto(Faker faker) { @@ -595,13 +595,17 @@ public class SchoolEntryProceduresPopulator extends BasePopulator<CreateProcedur faker.random().nextInt(0, 9), List.of(), faker.bool().bool(), - faker.bool().bool()); + randomBooleanWithUnknownSchoolEntry(faker)); } private static VaccinationSchemeValueDto randomVaccinationSchemeSchoolEntry(Faker faker) { return randomElement(faker, VaccinationSchemeValueDto.values()); } + private static BooleanWithUnknownDto randomBooleanWithUnknownSchoolEntry(Faker faker) { + return randomElement(faker, BooleanWithUnknownDto.values()); + } + @Override protected long countExistingEntities() { return this.schoolEntryProcedureRepository.count(); diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/testhelper/SchoolEntryTestHelperController.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/testhelper/SchoolEntryTestHelperController.java index 1a6e98172ce1e2c9815d7a7ff187410a9815af2c..d6bcdb129e8040639460d780b25008791d85338a 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/testhelper/SchoolEntryTestHelperController.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/testhelper/SchoolEntryTestHelperController.java @@ -5,7 +5,7 @@ package de.eshg.schoolentry.testhelper; -import de.eshg.auditlog.AuditLogTestHelperApi; +import de.eshg.auditlog.SharedAuditLogTestHelperApi; import de.eshg.lib.appointmentblock.LocationSelectionMode; import de.eshg.lib.appointmentblock.api.CreateAppointmentBlockGroupResponse; import de.eshg.lib.appointmentblock.spring.AppointmentBlockProperties; @@ -34,7 +34,7 @@ import org.springframework.web.service.annotation.PostExchange; @RestController @ConditionalOnTestHelperEnabled public class SchoolEntryTestHelperController extends TestHelperController - implements AuditLogTestHelperApi { + implements SharedAuditLogTestHelperApi { private final SchoolEntryTestHelperService schoolEntryTestHelperService; private final SchoolEntryFeatureToggle schoolEntryFeatureToggle; diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/util/ExceptionUtil.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/util/ExceptionUtil.java index 9f13b954d2f0d6aa3658ff9f1401e99d7ce89d38..a40c3bd17b0bab3befe9169b856b5d1109a4acca 100644 --- a/backend/school-entry/src/main/java/de/eshg/schoolentry/util/ExceptionUtil.java +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/util/ExceptionUtil.java @@ -30,4 +30,8 @@ public final class ExceptionUtil { "Location id is mandatory when location selection mode is %s" .formatted(LocationSelectionMode.HEALTH_DEPARTMENT)); } + + public static BadRequestException badRequestExceptionUnsupportedLocationMode() { + return new BadRequestException("Unsupported location mode"); + } } diff --git a/backend/school-entry/src/main/java/de/eshg/schoolentry/util/WaitingRoomSortKey.java b/backend/school-entry/src/main/java/de/eshg/schoolentry/util/WaitingRoomSortKey.java new file mode 100644 index 0000000000000000000000000000000000000000..3a06bfa2cd544e79c46eff1441ecb4b25a233f4b --- /dev/null +++ b/backend/school-entry/src/main/java/de/eshg/schoolentry/util/WaitingRoomSortKey.java @@ -0,0 +1,26 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.schoolentry.util; + +public enum WaitingRoomSortKey { + ID(false), + DATE_OF_BIRTH(true), + FIRSTNAME(true), + LASTNAME(true), + INFO(false), + STATUS(false), + MODIFIED_AT(false); + + private final boolean personAttribute; + + WaitingRoomSortKey(boolean personAttribute) { + this.personAttribute = personAttribute; + } + + public boolean isPersonAttribute() { + return personAttribute; + } +} diff --git a/backend/school-entry/src/main/resources/application-preview-features.properties b/backend/school-entry/src/main/resources/application-preview-features.properties index 067aa068818fbc3a59b395c4dfa40020ea005046..404ac134e0fbdb7d9c9f7f5e02ef1b8947cb1125 100644 --- a/backend/school-entry/src/main/resources/application-preview-features.properties +++ b/backend/school-entry/src/main/resources/application-preview-features.properties @@ -4,4 +4,7 @@ de.eshg.schoolentry.feature-toggle.enabled-new-features=\ CLOSE_PROCEDURE,\ SEARCH_BY_KNOWLEDGE_FACTORS,\ SCHOOL_YEAR,\ - SCHOOL_INFO_LETTER + SCHOOL_INFO_LETTER,\ + DELETE_PROCEDURE,\ + WAITING_ROOM,\ + REOPEN_PROCEDURE diff --git a/backend/school-entry/src/main/resources/migrations/0041_add_modified_at_waiting_room.xml b/backend/school-entry/src/main/resources/migrations/0041_add_modified_at_waiting_room.xml new file mode 100644 index 0000000000000000000000000000000000000000..42f895b0f78b03b3fbb6e72ded7509c6496c8388 --- /dev/null +++ b/backend/school-entry/src/main/resources/migrations/0041_add_modified_at_waiting_room.xml @@ -0,0 +1,20 @@ +<?xml version="1.1" encoding="UTF-8" standalone="no"?> +<!-- + Copyright 2024 cronn GmbH + SPDX-License-Identifier: AGPL-3.0-only +--> + +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" + xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"> + <changeSet author="GA-Lotse" id="1726577460077-1"> + <validCheckSum>9:d69dc982b9eba90e52b33d5c9447ee32</validCheckSum> + <addColumn tableName="waiting_room"> + <column name="modified_at" type="TIMESTAMP WITH TIME ZONE" + valueComputed="now()"> + <constraints nullable="false"/> + </column> + </addColumn> + </changeSet> +</databaseChangeLog> diff --git a/backend/school-entry/src/main/resources/migrations/0042_boolean_with_unknown.xml b/backend/school-entry/src/main/resources/migrations/0042_boolean_with_unknown.xml new file mode 100644 index 0000000000000000000000000000000000000000..4f0b9110dbf328f163a8b8795b21a5b7be5643d3 --- /dev/null +++ b/backend/school-entry/src/main/resources/migrations/0042_boolean_with_unknown.xml @@ -0,0 +1,95 @@ +<?xml version="1.1" encoding="UTF-8" standalone="no"?> +<!-- + Copyright 2024 cronn GmbH + SPDX-License-Identifier: AGPL-3.0-only +--> + +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" + xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"> + <changeSet author="GA-Lotse" id="1727090520141-2"> + <ext:createPostgresEnumType name="booleanwithunknown" + values="FALSE, TRUE, UNKNOWN"/> + <addColumn tableName="vaccination_status"> + <column name="perkombi_hbv_new" type="booleanwithunknown"/> + </addColumn> + <update tableName="vaccination_status"> + <column name="perkombi_hbv_new" + valueComputed="CAST(CASE WHEN perkombi_hbv THEN 'TRUE' ELSE 'FALSE' END AS booleanwithunknown)"/> + </update> + <dropColumn tableName="vaccination_status" columnName="perkombi_hbv"/> + <renameColumn tableName="vaccination_status" + oldColumnName="perkombi_hbv_new" + newColumnName="perkombi_hbv"/> + </changeSet> + <changeSet author="GA-Lotse" id="1727090520141-3"> + <addColumn tableName="anamnesis"> + <column name="u2_new" type="booleanwithunknown"/> + <column name="u3_new" type="booleanwithunknown"/> + <column name="u4_new" type="booleanwithunknown"/> + <column name="u5_new" type="booleanwithunknown"/> + <column name="u6_new" type="booleanwithunknown"/> + <column name="u7_new" type="booleanwithunknown"/> + <column name="u7a_new" type="booleanwithunknown"/> + <column name="u8_new" type="booleanwithunknown"/> + <column name="u9_new" type="booleanwithunknown"/> + </addColumn> + <update tableName="anamnesis"> + <column name="u2_new" + valueComputed="CAST(CASE WHEN u2 THEN 'TRUE' ELSE 'FALSE' END AS booleanwithunknown)"/> + <column name="u3_new" + valueComputed="CAST(CASE WHEN u2 THEN 'TRUE' ELSE 'FALSE' END AS booleanwithunknown)"/> + <column name="u4_new" + valueComputed="CAST(CASE WHEN u2 THEN 'TRUE' ELSE 'FALSE' END AS booleanwithunknown)"/> + <column name="u5_new" + valueComputed="CAST(CASE WHEN u2 THEN 'TRUE' ELSE 'FALSE' END AS booleanwithunknown)"/> + <column name="u6_new" + valueComputed="CAST(CASE WHEN u2 THEN 'TRUE' ELSE 'FALSE' END AS booleanwithunknown)"/> + <column name="u7_new" + valueComputed="CAST(CASE WHEN u2 THEN 'TRUE' ELSE 'FALSE' END AS booleanwithunknown)"/> + <column name="u7a_new" + valueComputed="CAST(CASE WHEN u2 THEN 'TRUE' ELSE 'FALSE' END AS booleanwithunknown)"/> + <column name="u8_new" + valueComputed="CAST(CASE WHEN u2 THEN 'TRUE' ELSE 'FALSE' END AS booleanwithunknown)"/> + <column name="u9_new" + valueComputed="CAST(CASE WHEN u2 THEN 'TRUE' ELSE 'FALSE' END AS booleanwithunknown)"/> + </update> + <dropColumn tableName="anamnesis" columnName="u2"/> + <dropColumn tableName="anamnesis" columnName="u3"/> + <dropColumn tableName="anamnesis" columnName="u4"/> + <dropColumn tableName="anamnesis" columnName="u5"/> + <dropColumn tableName="anamnesis" columnName="u6"/> + <dropColumn tableName="anamnesis" columnName="u7"/> + <dropColumn tableName="anamnesis" columnName="u7a"/> + <dropColumn tableName="anamnesis" columnName="u8"/> + <dropColumn tableName="anamnesis" columnName="u9"/> + <renameColumn tableName="anamnesis" + oldColumnName="u2_new" + newColumnName="u2"/> + <renameColumn tableName="anamnesis" + oldColumnName="u3_new" + newColumnName="u3"/> + <renameColumn tableName="anamnesis" + oldColumnName="u4_new" + newColumnName="u4"/> + <renameColumn tableName="anamnesis" + oldColumnName="u5_new" + newColumnName="u5"/> + <renameColumn tableName="anamnesis" + oldColumnName="u6_new" + newColumnName="u6"/> + <renameColumn tableName="anamnesis" + oldColumnName="u7_new" + newColumnName="u7"/> + <renameColumn tableName="anamnesis" + oldColumnName="u7a_new" + newColumnName="u7a"/> + <renameColumn tableName="anamnesis" + oldColumnName="u8_new" + newColumnName="u8"/> + <renameColumn tableName="anamnesis" + oldColumnName="u9_new" + newColumnName="u9"/> + </changeSet> +</databaseChangeLog> diff --git a/backend/school-entry/src/main/resources/migrations/changelog.xml b/backend/school-entry/src/main/resources/migrations/changelog.xml index e5004f745def81ff7abf7f92b58af9ba0545a6f1..f731ee3c0f5550e86904a3141e04e0a7de1aa6e3 100644 --- a/backend/school-entry/src/main/resources/migrations/changelog.xml +++ b/backend/school-entry/src/main/resources/migrations/changelog.xml @@ -50,5 +50,7 @@ <include file="migrations/0038_waiting_room_for_existing_procedures.xml"/> <include file="migrations/0039_add_consultant_to_appointment_blocks.xml"/> <include file="migrations/0040_procedure_sequences.xml"/> + <include file="/migrations/0041_add_modified_at_waiting_room.xml"/> + <include file="migrations/0042_boolean_with_unknown.xml"/> </databaseChangeLog> diff --git a/backend/school-entry/src/main/resources/templates/documents/privacy_notice.pdf b/backend/school-entry/src/main/resources/templates/documents/privacy_notice.pdf index f5f4b59042a7f830ef3fee54aa2428a36439224e..5e6a3314e8b3eabb0f55bafbae92600bc44dd9e8 100644 Binary files a/backend/school-entry/src/main/resources/templates/documents/privacy_notice.pdf and b/backend/school-entry/src/main/resources/templates/documents/privacy_notice.pdf differ diff --git a/backend/school-entry/src/main/resources/templates/documents/privacy_policy.pdf b/backend/school-entry/src/main/resources/templates/documents/privacy_policy.pdf index 5c3ff62c7d29987029e6e99d8e778b9ae7074c94..b102d85d0cd0fb89059e88b7e44b9a370493f4a4 100644 Binary files a/backend/school-entry/src/main/resources/templates/documents/privacy_policy.pdf and b/backend/school-entry/src/main/resources/templates/documents/privacy_policy.pdf differ diff --git a/backend/school-entry/src/main/resources/templates/invitation.ftlx b/backend/school-entry/src/main/resources/templates/invitation.ftlx index 42f2f5e0a006e376e7d9105da14ba5130a4af5de..1ea813ace20db5b2d1cfec5b5bcdb4c12a26becc 100644 --- a/backend/school-entry/src/main/resources/templates/invitation.ftlx +++ b/backend/school-entry/src/main/resources/templates/invitation.ftlx @@ -245,9 +245,9 @@ <td rowspan="2"> <div class="label">Adresse</div> <div class="data"> - <div>${office.name}</div> - <div>${office.street}</div> - <div>${office.zipCode} ${office.city}</div> + <div>${examination.executionLocation.name}</div> + <div>${examination.executionLocation.street}</div> + <div>${examination.executionLocation.zipCode} ${examination.executionLocation.city}</div> </div> </td> <td rowspan="2"> diff --git a/backend/service-commons/gradle.lockfile b/backend/service-commons/gradle.lockfile index 3274c4eb56db92e7cc8153fe0c0e989781075f94..59c488bdd2cda9b1557a7de9b51e94a4980faa25 100644 --- a/backend/service-commons/gradle.lockfile +++ b/backend/service-commons/gradle.lockfile @@ -1,16 +1,16 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson:jackson-bom:2.17.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testRuntimeClasspath @@ -47,20 +47,20 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,compileClasspath,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/service-commons/src/main/resources/logback-spring.xml b/backend/service-commons/src/main/resources/logback-spring.xml new file mode 100644 index 0000000000000000000000000000000000000000..bb00d79cf3c2cc0a17ffa9828bd6aab7dca81770 --- /dev/null +++ b/backend/service-commons/src/main/resources/logback-spring.xml @@ -0,0 +1,57 @@ +<!-- + Copyright 2024 cronn GmbH + SPDX-License-Identifier: Apache-2.0 +--> + +<configuration> + <include resource="org/springframework/boot/logging/logback/defaults.xml"/> + <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> + + <springProfile name="!(dev | production)"> + <root level="info"> + <appender-ref ref="CONSOLE" /> + </root> + </springProfile> + + <springProfile name="dev"> + <appender name="logstash-all-levels" class="ch.qos.logback.core.ConsoleAppender"> + <encoder class="net.logstash.logback.encoder.LogstashEncoder"/> + </appender> + + <root level="info"> + <appender-ref ref="logstash-all-levels" /> + </root> + </springProfile> + + <springProfile name="production"> +<!-- <property name="DEBUG_LOG_DIRECTORY" value="${DEBUG_LOG_DIRECTORY:-/logs}"/>--> + + <appender name="logstash-info" class="ch.qos.logback.core.ConsoleAppender"> + <encoder class="net.logstash.logback.encoder.LogstashEncoder"/> + <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> + <level>INFO</level> + </filter> + </appender> + + <!-- TODO: clarify the volume path --> +<!-- <appender name="debug-log" class="ch.qos.logback.core.rolling.RollingFileAppender">--> +<!-- <file>${DEBUG_LOG_DIRECTORY}/debug.log</file>--> + +<!-- <encoder>--> +<!-- <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} [%-5p] [%t] %-40.40logger{39} : %m%n%wEx</pattern>--> +<!-- <charset>UTF-8</charset>--> +<!-- </encoder>--> + +<!-- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">--> +<!-- <fileNamePattern>${DEBUG_LOG_DIRECTORY}/debug.log.%d{yyyy-MM-dd}</fileNamePattern>--> +<!-- <maxHistory>14</maxHistory>--> +<!-- </rollingPolicy>--> +<!-- </appender>--> + + <root level="info"> + <appender-ref ref="logstash-info" /> +<!-- <appender-ref ref="debug-log" />--> + </root> + </springProfile> + +</configuration> diff --git a/backend/service-commons/src/main/resources/logback.xml b/backend/service-commons/src/main/resources/logback.xml deleted file mode 100644 index b3869bd64d4fdc4562ce805510bbcef79771857a..0000000000000000000000000000000000000000 --- a/backend/service-commons/src/main/resources/logback.xml +++ /dev/null @@ -1,18 +0,0 @@ -<!-- - Copyright 2024 cronn GmbH - SPDX-License-Identifier: Apache-2.0 ---> - -<configuration> - <include resource="org/springframework/boot/logging/logback/defaults.xml"/> - <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> - - <appender name="LOGSTASH" class="ch.qos.logback.core.ConsoleAppender"> - <encoder class="net.logstash.logback.encoder.LogstashEncoder"> - </encoder> - </appender> - - <root level="info"> - <appender-ref ref="${LOG_TARGET:-CONSOLE}" /> - </root> -</configuration> \ No newline at end of file diff --git a/backend/service-directory/gradle.lockfile b/backend/service-directory/gradle.lockfile index 431e941a46b42644fd2e0248a1c07c516b285071..1ee6914a07dac24948b1c18a4e20f620d054544c 100644 --- a/backend/service-directory/gradle.lockfile +++ b/backend/service-directory/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -37,8 +38,8 @@ com.tngtech.archunit:archunit-junit5:1.3.0=productionRuntimeClasspath,runtimeCla com.tngtech.archunit:archunit:1.3.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -46,11 +47,11 @@ de.cronn:postgres-snapshot-util:1.1=productionRuntimeClasspath,runtimeClasspath, de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -58,14 +59,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -89,10 +89,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=productionRuntimeClasspath,ru org.apache.httpcomponents.core5:httpcore5:5.2.5=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -109,8 +109,8 @@ org.hamcrest:hamcrest-core:2.2=productionRuntimeClasspath,runtimeClasspath,testC org.hamcrest:hamcrest:2.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -136,7 +136,7 @@ org.opentest4j:opentest4j:1.3.0=compileClasspath,productionRuntimeClasspath,runt org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -144,29 +144,29 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -175,19 +175,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testCompileClasspath,testRuntimeClasspath org.testcontainers:junit-jupiter:1.19.8=testCompileClasspath,testRuntimeClasspath diff --git a/backend/settings.gradle b/backend/settings.gradle index 296d7159c311b9338f775ef0c165fc00d9a828d0..bd66948600411fc15eec2c127edbbf65c9a24284 100644 --- a/backend/settings.gradle +++ b/backend/settings.gradle @@ -16,7 +16,7 @@ dependencyResolutionManagement { versionCatalogs { libs { - version('keycloak', '25.0.4') + version('keycloak', '25.0.6') library('keycloak-admin-client', 'org.keycloak', 'keycloak-admin-client').versionRef('keycloak') library('keycloak-common', 'org.keycloak', 'keycloak-common').versionRef('keycloak') library('keycloak-core', 'org.keycloak', 'keycloak-core').versionRef('keycloak') @@ -99,5 +99,6 @@ include 'sti-protection' include 'test-commons' include 'test-helper-commons' include 'test-helper-commons-api' +include 'test-helper-commons-spring' include 'travel-medicine' include 'util-commons' diff --git a/backend/spatz-dns/gradle.lockfile b/backend/spatz-dns/gradle.lockfile index b7630d8cdd1cd872bfe2c81f1f31ea500a7e24fb..0dccf585508f79ea672a181febfba0ac3e39fbf0 100644 --- a/backend/spatz-dns/gradle.lockfile +++ b/backend/spatz-dns/gradle.lockfile @@ -1,12 +1,12 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testRuntimeClasspath @@ -42,20 +42,20 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,compileClasspath,developmentOnly,productionRuntimeClasspath,runtimeClasspath,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/spatz/gradle.lockfile b/backend/spatz/gradle.lockfile index aa6cc593ac9533789ab099b47926257026eb5bfe..ad9a2aa4d5381d1323eb19f3f241de00e557ac66 100644 --- a/backend/spatz/gradle.lockfile +++ b/backend/spatz/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -27,8 +27,9 @@ com.github.java-json-tools:msg-simple:1.2=productionRuntimeClasspath,runtimeClas com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.ibm.async:asyncutil:0.1.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath @@ -49,11 +50,11 @@ com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspat commons-codec:commons-codec:1.16.1=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.11.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-logging:commons-logging:1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -dnsjava:dnsjava:3.6.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +dnsjava:dnsjava:3.6.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.fabric8:kubernetes-client-api:6.10.0=testCompileClasspath,testRuntimeClasspath io.fabric8:kubernetes-client:6.10.0=testCompileClasspath,testRuntimeClasspath io.fabric8:kubernetes-httpclient-okhttp:6.10.0=testRuntimeClasspath @@ -80,34 +81,34 @@ io.fabric8:kubernetes-model-resource:6.10.0=testCompileClasspath,testRuntimeClas io.fabric8:kubernetes-model-scheduling:6.10.0=testCompileClasspath,testRuntimeClasspath io.fabric8:kubernetes-model-storageclass:6.10.0=testCompileClasspath,testRuntimeClasspath io.fabric8:zjsonpatch:0.3.0=testCompileClasspath,testRuntimeClasspath -io.github.hakky54:sslcontext-kickstart-for-netty:8.3.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.github.hakky54:sslcontext-kickstart:8.3.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-buffer:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec-dns:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec-http2:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec-http:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec-socks:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-codec:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-common:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-handler-proxy:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-handler:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-resolver-dns-classes-macos:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-resolver-dns-native-macos:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-resolver-dns:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-resolver:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-transport-classes-epoll:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-transport-native-epoll:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-transport-native-unix-common:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.netty:netty-transport:4.1.112.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.github.hakky54:sslcontext-kickstart-for-netty:8.3.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.github.hakky54:sslcontext-kickstart:8.3.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-buffer:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-dns:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-http2:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-http:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec-socks:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-codec:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-common:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-handler-proxy:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-handler:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver-dns-classes-macos:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver-dns-native-macos:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver-dns:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-resolver:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport-classes-epoll:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport-native-epoll:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport-native-unix-common:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.netty:netty-transport:4.1.113.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.projectreactor.netty:reactor-netty-core:1.1.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.projectreactor.netty:reactor-netty-http:1.1.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.projectreactor:reactor-core:3.6.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.projectreactor:reactor-core:3.6.10=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=testRuntimeClasspath @@ -135,9 +136,9 @@ org.apache.james:apache-mime4j-dom:0.8.9=productionRuntimeClasspath,runtimeClass org.apache.james:apache-mime4j-storage:0.8.9=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=testCompileClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath @@ -159,7 +160,7 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt @@ -187,9 +188,9 @@ org.junit.platform:junit-platform-commons:1.10.3=testCompileClasspath,testRuntim org.junit.platform:junit-platform-engine:1.10.3=testRuntimeClasspath org.junit.platform:junit-platform-launcher:1.10.3=testRuntimeClasspath org.junit:junit-bom:5.10.3=testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-admin-client:25.0.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-common:25.0.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.keycloak:keycloak-core:25.0.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.keycloak:keycloak-admin-client:25.0.6=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.keycloak:keycloak-common:25.0.6=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.keycloak:keycloak-core:25.0.6=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.latencyutils:LatencyUtils:2.0.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.mockito:mockito-core:5.11.0=testCompileClasspath,testRuntimeClasspath org.mockito:mockito-junit-jupiter:5.11.0=testCompileClasspath,testRuntimeClasspath @@ -198,40 +199,40 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.reactivestreams:reactive-streams:1.0.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.snakeyaml:snakeyaml-engine:2.7=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.retry:spring-retry:2.0.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.retry:spring-retry:2.0.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/spatz/src/main/resources/application.properties b/backend/spatz/src/main/resources/application.properties index ce965f7a34b7dc3175de518616aa34518338993c..cf772f4c0ded5651f98f19fcc1834913d92acda2 100644 --- a/backend/spatz/src/main/resources/application.properties +++ b/backend/spatz/src/main/resources/application.properties @@ -1,5 +1,4 @@ logging.level.org.zalando.logbook=TRACE -logging.level.de.eshg=TRACE # TODO: remove once relay-server connections work reliably on cluster logging.level.org.java_websocket=TRACE diff --git a/backend/statistics/gradle.lockfile b/backend/statistics/gradle.lockfile index 556dd92a2baaac3990752922398f897645065c7e..4f41af5a3bbf42bf8ddac3267253fcfa8ff9ff14 100644 --- a/backend/statistics/gradle.lockfile +++ b/backend/statistics/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -23,8 +23,9 @@ com.github.virtuald:curvesapi:1.08=compileClasspath,productionRuntimeClasspath,r com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -44,7 +45,7 @@ com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeCla com.zaxxer:SparseBitSet:1.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-codec:commons-codec:1.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath commons-io:commons-io:2.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -52,11 +53,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -64,14 +65,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-core-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-models-jakarta:2.2.23=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-core-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-models-jakarta:2.2.24=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -99,10 +99,10 @@ org.apache.logging.log4j:log4j-to-slf4j:2.23.1=compileClasspath,productionRuntim org.apache.poi:poi-ooxml-lite:5.3.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.poi:poi-ooxml:5.3.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.poi:poi:5.3.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlbeans:xmlbeans:5.2.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -120,9 +120,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -148,7 +148,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -156,30 +156,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -189,19 +189,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/statistics/openApi.yaml b/backend/statistics/openApi.yaml index 372e23a52269ef6082a37911c1149fbbe4abcb19..cb4b6c1b2b0081ff65f6b0f091869c638dd590ea 100644 --- a/backend/statistics/openApi.yaml +++ b/backend/statistics/openApi.yaml @@ -792,6 +792,14 @@ paths: description: OK tags: - TestHelper + /test-helper/finish-auto-reports: + post: + operationId: finishAutoReports + responses: + "200": + description: OK + tags: + - TestHelper /test-helper/population: post: operationId: populateDefaults diff --git a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportController.java b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportController.java index 54e092918ec02bc659b58972df64618b3d3c671f..045a373f522cc41cba821bc838b777185a044449 100644 --- a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportController.java +++ b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportController.java @@ -7,27 +7,14 @@ package de.eshg.statistics.aggregation; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -import de.eshg.base.user.api.UserDto; -import de.eshg.rest.service.error.BadRequestException; -import de.eshg.rest.service.error.NotFoundException; import de.eshg.rest.service.security.config.BaseUrls; -import de.eshg.statistics.api.EvaluationDto; import de.eshg.statistics.api.report.GetReportDetailPageResponse; import de.eshg.statistics.config.StatisticsFeature; import de.eshg.statistics.config.StatisticsFeatureToggle; -import de.eshg.statistics.mapper.EvaluationMapper; -import de.eshg.statistics.mapper.StatisticMapper; -import de.eshg.statistics.persistence.entity.AggregationResultState; -import de.eshg.statistics.persistence.entity.report.Report; -import de.eshg.statistics.persistence.repository.ReportRepository; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; -import java.util.List; -import java.util.Map; -import java.util.Set; import java.util.UUID; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.service.annotation.GetExchange; @@ -38,58 +25,21 @@ import org.springframework.web.service.annotation.HttpExchange; @Tag(name = "Report") public class ReportController { private final StatisticsFeatureToggle statisticsFeatureToggle; - private final ReportRepository reportRepository; - private final StatisticService statisticService; + private final ReportService reportService; public ReportController( - StatisticsFeatureToggle statisticsFeatureToggle, - ReportRepository reportRepository, - StatisticService statisticService) { + StatisticsFeatureToggle statisticsFeatureToggle, ReportService reportService) { this.statisticsFeatureToggle = statisticsFeatureToggle; - this.reportRepository = reportRepository; - this.statisticService = statisticService; + this.reportService = reportService; } @GetExchange(value = "/{reportId}", accept = APPLICATION_JSON_VALUE) @ApiResponse(responseCode = "200", description = "The information for the detail page") @Operation(summary = "Get the information for the detail page") - @Transactional(readOnly = true) public GetReportDetailPageResponse getReportDetailPage( @PathVariable(name = "reportId") UUID reportId) { statisticsFeatureToggle.assertNewFeatureIsEnabled(StatisticsFeature.REPORTS); - Report report = getReportInternal(reportId); - validateReportCompleted(report); - Map<UUID, UserDto> resolvedUsers = - statisticService.getResolvedUsers(Set.of(report.getCreatedByUserId())); - List<EvaluationDto> evaluations = EvaluationMapper.getEvaluations(report.getEvaluations()); - - return new GetReportDetailPageResponse( - report.getExternalId(), - report.getReportSeries().getExternalId(), - report.getName(), - report.getReportSeries().getDescription(), - report.getReportSeries().getReports().size(), - report.getTimeRangeStart(), - report.getTimeRangeEnd(), - report.getCreatedAt(), - StatisticMapper.mapToApi(report.getTableColumns()), - report.getNumberOfTableRows(), - resolvedUsers.get(report.getCreatedByUserId()), - evaluations); - } - - private Report getReportInternal(UUID reportId) { - return reportRepository - .findByExternalId(reportId) - .orElseThrow( - () -> new NotFoundException("Report with id '%s' not found".formatted(reportId))); - } - - private void validateReportCompleted(Report report) { - if (!report.getState().equals(AggregationResultState.COMPLETED)) { - throw new BadRequestException( - "Report %s is not in state COMPLETED".formatted(report.getExternalId())); - } + return reportService.getReportDetailPage(reportId); } } diff --git a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportExecution.java b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportExecution.java new file mode 100644 index 0000000000000000000000000000000000000000..972852fd3dab079400eacd77b0951a8324e107b9 --- /dev/null +++ b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportExecution.java @@ -0,0 +1,100 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.statistics.aggregation; + +import de.eshg.lib.rest.oauth.client.commons.ModuleClientAuthenticator; +import de.eshg.statistics.api.AddDiagramRequest; +import de.eshg.statistics.api.EvaluationDto; +import de.eshg.statistics.persistence.entity.AggregationResultPendingState; +import de.eshg.statistics.persistence.entity.AggregationResultState; +import java.util.Map; +import java.util.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +public class ReportExecution { + private final ModuleClientAuthenticator moduleClientAuthenticator; + private final ReportService reportService; + private final DiagramCreationService diagramCreationService; + + private static final Logger log = LoggerFactory.getLogger(ReportExecution.class); + + public ReportExecution( + ModuleClientAuthenticator moduleClientAuthenticator, + ReportService reportService, + DiagramCreationService diagramCreationService) { + this.moduleClientAuthenticator = moduleClientAuthenticator; + this.reportService = reportService; + this.diagramCreationService = diagramCreationService; + } + + @Scheduled(cron = "${de.eshg.statistics.auto-report.schedule:@daily}") + public void handlePlannedReports() { + UUID reportId = reportService.getPlannedReportToExecuteSetToPending(); + while (reportId != null) { + createNewPlannedReport(reportId); + completeReport(reportId); + UUID nextReportId = reportService.getPlannedReportToExecuteSetToPending(); + if (reportId.equals(nextReportId)) { + // prevent endless loop + reportId = null; + } else { + reportId = nextReportId; + } + } + } + + private void createNewPlannedReport(UUID reportId) { + try { + moduleClientAuthenticator.doWithModuleClientAuthentication( + () -> reportService.createNewPlannedReportInSeries(reportId)); + } catch (Exception e) { + log.error("Could not complete report {}", reportId, e); + setToFailed(reportId); + } + } + + public void completeReport(UUID reportId) { + try { + ReportStateInformation stateInfo = reportService.getReportStateInformation(reportId); + while (stateInfo.state().equals(AggregationResultState.PENDING)) { + AggregationResultPendingState pendingState = stateInfo.pendingState(); + moduleClientAuthenticator.doWithModuleClientAuthentication( + () -> { + switch (pendingState) { + case DATA_AGGREGATION -> reportService.aggregateData(reportId); + case MIN_MAX_DETERMINATION -> reportService.minMaxDetermination(reportId); + case EVALUATION_CONDUCTION -> reportService.evaluationConduction(reportId); + case COPY_ONGOING -> + throw new IllegalStateException( + "Report of series %s in copy ongoing state".formatted(reportId)); + case DIAGRAM_CREATION -> { + Map<EvaluationDto, AddDiagramRequest> map = + reportService.findMissingDiagramOrCompleteAutoReport(reportId); + if (!map.isEmpty()) { + Map.Entry<EvaluationDto, AddDiagramRequest> entry = + map.entrySet().iterator().next(); + diagramCreationService.createDiagram(entry.getKey(), entry.getValue()); + } + } + } + }); + stateInfo = reportService.getReportStateInformation(reportId); + } + } catch (Exception e) { + log.error("Could not complete report {}", reportId, e); + setToFailed(reportId); + } + } + + private void setToFailed(UUID reportId) { + moduleClientAuthenticator.doWithModuleClientAuthentication( + () -> reportService.setStateToFailed(reportId)); + } +} diff --git a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportSeriesController.java b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportSeriesController.java index d8299efe98c0cef915ac084290c5caee0446a2e1..bdfa6b8920f95e279a9387a946600940226ec5d4 100644 --- a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportSeriesController.java +++ b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportSeriesController.java @@ -7,10 +7,7 @@ package de.eshg.statistics.aggregation; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -import de.eshg.lib.rest.oauth.client.commons.ModuleClientAuthenticator; import de.eshg.rest.service.security.config.BaseUrls; -import de.eshg.statistics.api.AddDiagramRequest; -import de.eshg.statistics.api.EvaluationDto; import de.eshg.statistics.api.report.AbstractAddReportSeriesRequest; import de.eshg.statistics.api.report.AddManualReportSeriesRequest; import de.eshg.statistics.api.report.GetReportsRequest; @@ -19,13 +16,10 @@ import de.eshg.statistics.api.report.ReportSeriesDto; import de.eshg.statistics.api.report.UpdateReportSeriesRequest; import de.eshg.statistics.config.StatisticsFeature; import de.eshg.statistics.config.StatisticsFeatureToggle; -import de.eshg.statistics.persistence.entity.AggregationResultPendingState; -import de.eshg.statistics.persistence.entity.AggregationResultState; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; -import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; import org.springframework.web.bind.annotation.PathVariable; @@ -41,19 +35,16 @@ import org.springframework.web.service.annotation.PostExchange; @Tag(name = "ReportSeries") public class ReportSeriesController { private final ReportSeriesService reportSeriesService; + private final ReportExecution reportExecution; private final StatisticsFeatureToggle statisticsFeatureToggle; - private final ModuleClientAuthenticator moduleClientAuthenticator; - private final DiagramCreationService diagramCreationService; public ReportSeriesController( ReportSeriesService reportSeriesService, - StatisticsFeatureToggle statisticsFeatureToggle, - ModuleClientAuthenticator moduleClientAuthenticator, - DiagramCreationService diagramCreationService) { + ReportExecution reportExecution, + StatisticsFeatureToggle statisticsFeatureToggle) { this.reportSeriesService = reportSeriesService; + this.reportExecution = reportExecution; this.statisticsFeatureToggle = statisticsFeatureToggle; - this.moduleClientAuthenticator = moduleClientAuthenticator; - this.diagramCreationService = diagramCreationService; } @PostExchange(accept = APPLICATION_JSON_VALUE) @@ -64,41 +55,9 @@ public class ReportSeriesController { statisticsFeatureToggle.assertNewFeatureIsEnabled(StatisticsFeature.REPORTS); ReportSeriesDto reportSeriesDto = reportSeriesService.addReportSeries(addReportSeriesRequest); - UUID uuid = reportSeriesDto.id(); if (addReportSeriesRequest instanceof AddManualReportSeriesRequest) { CompletableFuture.runAsync( - () -> { - ReportStateInformation stateInfo = - reportSeriesService.getReportStateInformationManualSeries(uuid); - while (stateInfo.state().equals(AggregationResultState.PENDING)) { - AggregationResultPendingState pendingState = stateInfo.pendingState(); - moduleClientAuthenticator.doWithModuleClientAuthentication( - () -> { - switch (pendingState) { - case DATA_AGGREGATION -> - reportSeriesService.aggregateDataManualReportSeries(uuid); - case MIN_MAX_DETERMINATION -> - reportSeriesService.minMaxDeterminationManualReportSeries(uuid); - case EVALUATION_CONDUCTION -> - reportSeriesService.evaluationConductionManualReportSeries(uuid); - case COPY_ONGOING -> - throw new IllegalStateException( - "Report of series %s in copy ongoing state".formatted(uuid)); - case DIAGRAM_CREATION -> { - Map<EvaluationDto, AddDiagramRequest> map = - reportSeriesService.findMissingDiagramOrCompleteManualReportSeries( - uuid); - if (!map.isEmpty()) { - Map.Entry<EvaluationDto, AddDiagramRequest> entry = - map.entrySet().iterator().next(); - diagramCreationService.createDiagram(entry.getKey(), entry.getValue()); - } - } - } - }); - stateInfo = reportSeriesService.getReportStateInformationManualSeries(uuid); - } - }); + () -> reportExecution.completeReport(reportSeriesDto.reportInfos().getFirst().id())); } return reportSeriesDto; } diff --git a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportSeriesService.java b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportSeriesService.java index 33156c2b18bb642b8f3651c958ba41b57b523d9e..f0f6d7c4c9594a8ecc70dc7b255a2121afc41db2 100644 --- a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportSeriesService.java +++ b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportSeriesService.java @@ -5,68 +5,34 @@ package de.eshg.statistics.aggregation; -import static de.eshg.statistics.persistence.entity.AggregationResultPendingState.DATA_AGGREGATION; -import static de.eshg.statistics.persistence.entity.AggregationResultPendingState.DIAGRAM_CREATION; -import static de.eshg.statistics.persistence.entity.AggregationResultPendingState.EVALUATION_CONDUCTION; -import static de.eshg.statistics.persistence.entity.AggregationResultPendingState.MIN_MAX_DETERMINATION; - import de.eshg.base.user.api.UserDto; import de.eshg.domain.model.BaseEntity_; import de.eshg.lib.keycloak.EmployeePermissionRole; import de.eshg.rest.service.error.BadRequestException; import de.eshg.rest.service.error.NotFoundException; import de.eshg.rest.service.security.CurrentUserHelper; -import de.eshg.statistics.api.AddDiagramRequest; -import de.eshg.statistics.api.EvaluationDto; -import de.eshg.statistics.api.chart.HistogramChartConfigurationDto; -import de.eshg.statistics.api.filter.BooleanFilterParameterDto; -import de.eshg.statistics.api.filter.DecimalRangeFilterParameterDto; -import de.eshg.statistics.api.filter.DecimalValueFilterParameterDto; -import de.eshg.statistics.api.filter.IntegerRangeFilterParameterDto; -import de.eshg.statistics.api.filter.IntegerValueFilterParameterDto; -import de.eshg.statistics.api.filter.NullFilterParameterDto; -import de.eshg.statistics.api.filter.TableColumnFilterParameter; -import de.eshg.statistics.api.filter.TextFilterParameterDto; -import de.eshg.statistics.api.filter.ValueOptionFilterParameterDto; import de.eshg.statistics.api.report.AbstractAddReportSeriesRequest; import de.eshg.statistics.api.report.AddAutoReportSeriesRequest; import de.eshg.statistics.api.report.AddManualReportSeriesRequest; import de.eshg.statistics.api.report.GetReportsRequest; import de.eshg.statistics.api.report.GetReportsResponse; import de.eshg.statistics.api.report.ReportSeriesDto; -import de.eshg.statistics.api.report.ReportingPeriodDto; import de.eshg.statistics.api.report.UpdateReportSeriesRequest; -import de.eshg.statistics.mapper.EvaluationMapper; -import de.eshg.statistics.mapper.FilterParameterMapper; import de.eshg.statistics.mapper.ReportMapper; import de.eshg.statistics.mapper.StatisticMapper; -import de.eshg.statistics.persistence.entity.AggregationResultPendingState; import de.eshg.statistics.persistence.entity.AggregationResultState; -import de.eshg.statistics.persistence.entity.ChartConfiguration; -import de.eshg.statistics.persistence.entity.Diagram; -import de.eshg.statistics.persistence.entity.Evaluation; import de.eshg.statistics.persistence.entity.Statistic; -import de.eshg.statistics.persistence.entity.chart.HistogramChartConfiguration; import de.eshg.statistics.persistence.entity.report.Report; import de.eshg.statistics.persistence.entity.report.ReportSeries; import de.eshg.statistics.persistence.entity.report.ReportType; import de.eshg.statistics.persistence.repository.ReportSeriesRepository; import java.time.Clock; -import java.time.Instant; import java.time.LocalDate; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.hibernate.Hibernate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; @@ -77,29 +43,21 @@ import org.springframework.transaction.annotation.Transactional; public class ReportSeriesService { private final ReportSeriesRepository reportSeriesRepository; private final StatisticService statisticService; - private final DataAggregationService dataAggregationService; - private final EvaluationService evaluationService; private final Clock clock; - private static final Logger log = LoggerFactory.getLogger(ReportSeriesService.class); - public ReportSeriesService( ReportSeriesRepository reportSeriesRepository, StatisticService statisticService, - DataAggregationService dataAggregationService, - EvaluationService evaluationService, Clock clock) { this.reportSeriesRepository = reportSeriesRepository; this.statisticService = statisticService; - this.dataAggregationService = dataAggregationService; - this.evaluationService = evaluationService; this.clock = clock; } @Transactional public ReportSeriesDto addReportSeries(AbstractAddReportSeriesRequest addReportSeriesRequest) { Statistic statistic = statisticService.getStatistic(addReportSeriesRequest.statisticId()); - if (hasNoDiagrams(statistic)) { + if (StatisticService.hasNoDiagrams(statistic)) { throw new BadRequestException("Report creation is only possible with existing diagrams"); } @@ -117,12 +75,6 @@ public class ReportSeriesService { return ReportMapper.mapToApi(reportSeries); } - private static boolean hasNoDiagrams(Statistic statistic) { - return statistic.getEvaluations().isEmpty() - || statistic.getEvaluations().stream() - .allMatch(evaluation -> evaluation.getDiagrams().isEmpty()); - } - private static ReportSeries createManualReportSeries( Statistic statistic, AddManualReportSeriesRequest addManualReportSeriesRequest) { AggregationResultUtil.validateTimeRange( @@ -136,7 +88,7 @@ public class ReportSeriesService { reportSeries.setTimeRangeEnd(addManualReportSeriesRequest.timeRangeEnd()); reportSeries.addReport( - createReport( + ReportService.createReport( addManualReportSeriesRequest.name(), addManualReportSeriesRequest.timeRangeStart(), addManualReportSeriesRequest.timeRangeEnd(), @@ -161,10 +113,10 @@ public class ReportSeriesService { LocalDate executionAndEndDate = calculateExecutionDate(addAutoReportSeriesRequest.startMonth()); LocalDate dateStart = - calculateStartDate(addAutoReportSeriesRequest.reportingPeriod(), executionAndEndDate); + ReportService.calculateStartDate(reportSeries.getPeriod(), executionAndEndDate); reportSeries.addReport( - createReport( + ReportService.createReport( "1", dateStart.atStartOfDay(clock.getZone()).toInstant(), executionAndEndDate.atStartOfDay(clock.getZone()).toInstant(), @@ -187,45 +139,6 @@ public class ReportSeriesService { return LocalDate.of(startYear, startMonth, 1); } - private static LocalDate calculateStartDate( - ReportingPeriodDto reportingPeriodDto, LocalDate executionDate) { - return switch (reportingPeriodDto) { - case MONTH -> executionDate.minusMonths(1); - case THREE_MONTHS -> executionDate.minusMonths(3); - case HALF_YEAR -> executionDate.minusMonths(6); - case YEAR -> executionDate.minusMonths(12); - }; - } - - private static Report createReport( - String name, - Instant timeRangeStart, - Instant timeRangeEnd, - AggregationResultState state, - LocalDate executionDate, - Statistic statistic) { - Report report = new Report(); - report.setName(name); - report.setTimeRangeStart(timeRangeStart); - report.setTimeRangeEnd(timeRangeEnd); - report.setNumberOfTableRows(0); - report.setState(state); - report.setPendingState(state.equals(AggregationResultState.PENDING) ? DATA_AGGREGATION : null); - report.setExecutionDate(executionDate); - - report.addTableColumns( - statistic.getTableColumns().stream() - .map(StatisticCopyService::copyTableColumnWithoutCellEntriesWithoutMinMaxValues) - .toList()); - return report; - } - - @Transactional(readOnly = true) - public ReportStateInformation getReportStateInformationManualSeries(UUID reportSeriesId) { - Report report = getReportSeriesInternal(reportSeriesId).getReports().getFirst(); - return new ReportStateInformation(report.getState(), report.getPendingState()); - } - private ReportSeries getReportSeriesInternal(UUID reportSeriesId) { return reportSeriesRepository .findByExternalId(reportSeriesId) @@ -235,271 +148,6 @@ public class ReportSeriesService { "Report series with id '%s' not found".formatted(reportSeriesId))); } - @Transactional - public void aggregateDataManualReportSeries(UUID reportSeriesId) { - ReportSeries reportSeries = getReportSeriesInternal(reportSeriesId); - Report report = reportSeries.getReports().getFirst(); - if (wrongConstellationForMethod( - reportSeries, report, DATA_AGGREGATION, "aggregateDataManualReportSeries")) { - return; - } - - try { - dataAggregationService.collectTableRows(report); - } catch (Exception exception) { - log.error("Error while collecting table rows", exception); - report.setState(AggregationResultState.FAILED); - } - } - - private static boolean wrongConstellationForMethod( - ReportSeries reportSeries, - Report report, - AggregationResultPendingState expectedPendingState, - String method) { - if (!report.getState().equals(AggregationResultState.PENDING) - || !reportSeries.getReportType().equals(ReportType.MANUAL) - || !report.getPendingState().equals(expectedPendingState)) { - - log.error( - "'{}' called for wrong constellation {} {} {}", - method, - report.getState(), - reportSeries.getReportType(), - report.getPendingState()); - report.setState(AggregationResultState.FAILED); - return true; - } - return false; - } - - @Transactional - public void minMaxDeterminationManualReportSeries(UUID reportSeriesId) { - ReportSeries reportSeries = getReportSeriesInternal(reportSeriesId); - Report report = reportSeries.getReports().getFirst(); - if (wrongConstellationForMethod( - reportSeries, report, MIN_MAX_DETERMINATION, "minMaxDeterminationManualReportSeries")) { - return; - } - - dataAggregationService.determineMinMaxNullUnknownValues(report); - report.setPendingState(EVALUATION_CONDUCTION); - } - - @Transactional - public void evaluationConductionManualReportSeries(UUID reportSeriesId) { - ReportSeries reportSeries = getReportSeriesInternal(reportSeriesId); - Report report = reportSeries.getReports().getFirst(); - if (wrongConstellationForMethod( - reportSeries, report, EVALUATION_CONDUCTION, "evaluationConductionManualReportSeries")) { - return; - } - - Statistic statistic = reportSeries.getStatistic(); - if (hasNoDiagrams(statistic)) { - finishReport(report); - } else { - copyEvaluationsWithoutDiagrams(report, statistic); - report.setPendingState(DIAGRAM_CREATION); - } - } - - private static void finishReport(Report report) { - report.setPendingState(null); - report.setState(AggregationResultState.COMPLETED); - } - - private void copyEvaluationsWithoutDiagrams(Report report, Statistic statistic) { - statistic.getEvaluations().stream() - .filter(evaluation -> !evaluation.getDiagrams().isEmpty()) - .forEach( - evaluation -> report.addEvaluation(copyEvaluationWithoutDiagrams(evaluation, report))); - } - - private Evaluation copyEvaluationWithoutDiagrams(Evaluation original, Report report) { - ChartConfiguration originalChartConfiguration = - Hibernate.unproxy(original.getChartConfiguration(), ChartConfiguration.class); - ChartConfiguration chartConfiguration = - StatisticCopyService.copyChartConfiguration(originalChartConfiguration, false); - - if (chartConfiguration instanceof HistogramChartConfiguration histogramChartConfiguration) { - HistogramChartConfigurationDto chartConfigurationDto = - EvaluationMapper.mapToHistogramChartConfigurationDto(histogramChartConfiguration); - histogramChartConfiguration.addBins( - evaluationService.calculateHistogramBins(chartConfigurationDto, report)); - } - - Evaluation evaluation = new Evaluation(); - evaluation.setOriginalEvaluationId(original.getExternalId()); - evaluation.setName(original.getName()); - evaluation.setChartConfiguration(chartConfiguration); - return evaluation; - } - - @Transactional - public Map<EvaluationDto, AddDiagramRequest> findMissingDiagramOrCompleteManualReportSeries( - UUID reportSeriesId) { - ReportSeries reportSeries = getReportSeriesInternal(reportSeriesId); - Report report = reportSeries.getReports().getFirst(); - if (wrongConstellationForMethod( - reportSeries, report, DIAGRAM_CREATION, "findMissingDiagramsOrCompleteReport")) { - return Collections.emptyMap(); - } - - Optional<Evaluation> firstUnfinishedEvaluation = - report.getEvaluations().stream() - .filter(evaluation -> evaluation.getOriginalEvaluationId() != null) - .findFirst(); - if (firstUnfinishedEvaluation.isEmpty()) { - finishReport(report); - return Collections.emptyMap(); - } - - Evaluation evaluationToComplete = firstUnfinishedEvaluation.get(); - - Optional<Diagram> diagramToCopyOptional = Optional.empty(); - try { - Evaluation originalEvaluation = - evaluationService.getEvaluationInternal(evaluationToComplete.getOriginalEvaluationId()); - diagramToCopyOptional = - originalEvaluation.getDiagrams().stream() - .filter(diagram -> notAlreadyCopied(evaluationToComplete, diagram)) - .findFirst(); - } catch (NotFoundException e) { - // Evaluation deleted - log.warn( - "Could not finish diagrams for report %s, evaluation %s: %s" - .formatted( - report.getExternalId(), evaluationToComplete.getExternalId(), e.getMessage())); - } - if (diagramToCopyOptional.isEmpty()) { - evaluationToComplete.setOriginalEvaluationId(null); - return Collections.emptyMap(); - } - - Diagram diagramToCopy = diagramToCopyOptional.get(); - return Map.of( - EvaluationMapper.mapToApi(evaluationToComplete, true), - new AddDiagramRequest( - diagramToCopy.getTitle(), - diagramToCopy.getDescription(), - FilterParameterMapper.mapToApi(diagramToCopy.getFilters()))); - } - - private boolean notAlreadyCopied(Evaluation evaluationToComplete, Diagram diagram) { - return evaluationToComplete.getDiagrams().stream() - .noneMatch(copiedDiagram -> isIdentical(copiedDiagram, diagram)); - } - - private boolean isIdentical(Diagram copiedDiagram, Diagram originalDiagram) { - return copiedDiagram.getTitle().equals(originalDiagram.getTitle()) - && Objects.equals(copiedDiagram.getDescription(), originalDiagram.getDescription()) - && identicalFilters( - FilterParameterMapper.mapToApi(copiedDiagram.getFilters()), - FilterParameterMapper.mapToApi(originalDiagram.getFilters())); - } - - private boolean identicalFilters( - List<TableColumnFilterParameter> copiedColumnFilters, - List<TableColumnFilterParameter> originalTableColumnFilters) { - if (copiedColumnFilters.size() != originalTableColumnFilters.size()) { - return false; - } - - return copiedColumnFilters.stream() - .allMatch( - columnFilter -> - identicalColumnFilterPresent(columnFilter, originalTableColumnFilters)) - && originalTableColumnFilters.stream() - .allMatch( - columnFilter -> identicalColumnFilterPresent(columnFilter, copiedColumnFilters)); - } - - private boolean identicalColumnFilterPresent( - TableColumnFilterParameter columnFilterToFind, List<TableColumnFilterParameter> filters) { - return filters.stream().anyMatch(filter -> isIdentical(filter, columnFilterToFind)); - } - - private boolean isIdentical( - TableColumnFilterParameter filter, TableColumnFilterParameter columnFilterToFind) { - if (!filter.type().equals(columnFilterToFind.type()) - || !filter - .attribute() - .businessModuleName() - .equals(columnFilterToFind.attribute().businessModuleName()) - || !filter.attribute().dataSourceId().equals(columnFilterToFind.attribute().dataSourceId()) - || !filter - .attribute() - .businessModuleAttributeCode() - .equals(columnFilterToFind.attribute().businessModuleAttributeCode()) - || !Objects.equals( - filter.attribute().baseModuleAttributeCode(), - columnFilterToFind.attribute().baseModuleAttributeCode())) { - return false; - } - return switch (filter) { - case BooleanFilterParameterDto booleanFilter: - { - BooleanFilterParameterDto otherFilter = (BooleanFilterParameterDto) columnFilterToFind; - yield booleanFilter.searchForTrue() == otherFilter.searchForTrue() - && booleanFilter.searchForFalse() == otherFilter.searchForFalse() - && booleanFilter.searchForNull() == otherFilter.searchForNull(); - } - case DecimalRangeFilterParameterDto decimalRangeFilter: - { - DecimalRangeFilterParameterDto otherFilter = - (DecimalRangeFilterParameterDto) columnFilterToFind; - yield decimalRangeFilter.minValueInclusive().compareTo(otherFilter.minValueInclusive()) - == 0 - && decimalRangeFilter.maxValueInclusive().compareTo(otherFilter.maxValueInclusive()) - == 0 - && decimalRangeFilter.withNullValues() == otherFilter.withNullValues(); - } - case DecimalValueFilterParameterDto decimalValueFilter: - { - DecimalValueFilterParameterDto otherFilter = - (DecimalValueFilterParameterDto) columnFilterToFind; - yield decimalValueFilter.value().compareTo(otherFilter.value()) == 0 - && decimalValueFilter.numericComparison().equals(otherFilter.numericComparison()) - && decimalValueFilter.withNullValues() == otherFilter.withNullValues(); - } - case IntegerRangeFilterParameterDto integerRangeFilter: - { - IntegerRangeFilterParameterDto otherFilter = - (IntegerRangeFilterParameterDto) columnFilterToFind; - yield integerRangeFilter.minValueInclusive().equals(otherFilter.minValueInclusive()) - && integerRangeFilter.maxValueInclusive().equals(otherFilter.maxValueInclusive()) - && integerRangeFilter.withNullValues() == otherFilter.withNullValues(); - } - case IntegerValueFilterParameterDto integerValueFilter: - { - IntegerValueFilterParameterDto otherFilter = - (IntegerValueFilterParameterDto) columnFilterToFind; - yield integerValueFilter.value().equals(otherFilter.value()) - && integerValueFilter.numericComparison().equals(otherFilter.numericComparison()) - && integerValueFilter.withNullValues() == otherFilter.withNullValues(); - } - case NullFilterParameterDto ignored: - { - yield true; - } - case TextFilterParameterDto textFilter: - { - yield textFilter.text().equals(((TextFilterParameterDto) columnFilterToFind).text()); - } - case ValueOptionFilterParameterDto valueOptionFilter: - { - ValueOptionFilterParameterDto otherFilter = - (ValueOptionFilterParameterDto) columnFilterToFind; - Set<String> searchValueSet = new HashSet<>(valueOptionFilter.searchValues()); - Set<String> otherSearchValueSet = new HashSet<>(otherFilter.searchValues()); - yield searchValueSet.containsAll(otherFilter.searchValues()) - && otherSearchValueSet.containsAll(valueOptionFilter.searchValues()) - && valueOptionFilter.searchForNull() == otherFilter.searchForNull(); - } - }; - } - @Transactional public ReportSeriesDto updateReportSeries( UUID reportSeriesId, UpdateReportSeriesRequest updateReportSeriesRequest) { diff --git a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportService.java b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportService.java new file mode 100644 index 0000000000000000000000000000000000000000..77149475021847c68a4d68bb8804417c92e818e6 --- /dev/null +++ b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/ReportService.java @@ -0,0 +1,491 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.statistics.aggregation; + +import de.eshg.base.user.api.UserDto; +import de.eshg.rest.service.error.BadRequestException; +import de.eshg.rest.service.error.NotFoundException; +import de.eshg.statistics.api.AddDiagramRequest; +import de.eshg.statistics.api.EvaluationDto; +import de.eshg.statistics.api.chart.HistogramChartConfigurationDto; +import de.eshg.statistics.api.filter.BooleanFilterParameterDto; +import de.eshg.statistics.api.filter.DecimalRangeFilterParameterDto; +import de.eshg.statistics.api.filter.DecimalValueFilterParameterDto; +import de.eshg.statistics.api.filter.IntegerRangeFilterParameterDto; +import de.eshg.statistics.api.filter.IntegerValueFilterParameterDto; +import de.eshg.statistics.api.filter.NullFilterParameterDto; +import de.eshg.statistics.api.filter.TableColumnFilterParameter; +import de.eshg.statistics.api.filter.TextFilterParameterDto; +import de.eshg.statistics.api.filter.ValueOptionFilterParameterDto; +import de.eshg.statistics.api.report.GetReportDetailPageResponse; +import de.eshg.statistics.mapper.EvaluationMapper; +import de.eshg.statistics.mapper.FilterParameterMapper; +import de.eshg.statistics.mapper.StatisticMapper; +import de.eshg.statistics.persistence.entity.AggregationResultPendingState; +import de.eshg.statistics.persistence.entity.AggregationResultState; +import de.eshg.statistics.persistence.entity.ChartConfiguration; +import de.eshg.statistics.persistence.entity.Diagram; +import de.eshg.statistics.persistence.entity.Evaluation; +import de.eshg.statistics.persistence.entity.Statistic; +import de.eshg.statistics.persistence.entity.chart.HistogramChartConfiguration; +import de.eshg.statistics.persistence.entity.report.Frequency; +import de.eshg.statistics.persistence.entity.report.Report; +import de.eshg.statistics.persistence.entity.report.ReportSeries; +import de.eshg.statistics.persistence.entity.report.ReportType; +import de.eshg.statistics.persistence.entity.report.ReportingPeriod; +import de.eshg.statistics.persistence.repository.ReportRepository; +import java.time.Clock; +import java.time.Instant; +import java.time.LocalDate; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import org.hibernate.Hibernate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class ReportService { + private final ReportRepository reportRepository; + private final StatisticService statisticService; + private final Clock clock; + private final DataAggregationService dataAggregationService; + private final EvaluationService evaluationService; + + private static final Logger log = LoggerFactory.getLogger(ReportService.class); + + public ReportService( + ReportRepository reportRepository, + StatisticService statisticService, + Clock clock, + DataAggregationService dataAggregationService, + EvaluationService evaluationService) { + this.reportRepository = reportRepository; + this.statisticService = statisticService; + this.clock = clock; + this.dataAggregationService = dataAggregationService; + this.evaluationService = evaluationService; + } + + static Report createReport( + String name, + Instant timeRangeStart, + Instant timeRangeEnd, + AggregationResultState state, + LocalDate executionDate, + Statistic statistic) { + Report report = new Report(); + report.setName(name); + report.setTimeRangeStart(timeRangeStart); + report.setTimeRangeEnd(timeRangeEnd); + report.setNumberOfTableRows(0); + report.setState(state); + report.setPendingState( + state.equals(AggregationResultState.PENDING) + ? AggregationResultPendingState.DATA_AGGREGATION + : null); + report.setExecutionDate(executionDate); + + report.addTableColumns( + statistic.getTableColumns().stream() + .map(StatisticCopyService::copyTableColumnWithoutCellEntriesWithoutMinMaxValues) + .toList()); + return report; + } + + @Transactional(readOnly = true) + public GetReportDetailPageResponse getReportDetailPage(UUID reportId) { + Report report = getReportInternal(reportId); + validateReportCompleted(report); + Map<UUID, UserDto> resolvedUsers = + statisticService.getResolvedUsers(Set.of(report.getCreatedByUserId())); + List<EvaluationDto> evaluations = EvaluationMapper.getEvaluations(report.getEvaluations()); + + return new GetReportDetailPageResponse( + report.getExternalId(), + report.getReportSeries().getExternalId(), + report.getName(), + report.getReportSeries().getDescription(), + report.getReportSeries().getReports().size(), + report.getTimeRangeStart(), + report.getTimeRangeEnd(), + report.getCreatedAt(), + StatisticMapper.mapToApi(report.getTableColumns()), + report.getNumberOfTableRows(), + resolvedUsers.get(report.getCreatedByUserId()), + evaluations); + } + + private Report getReportInternal(UUID reportId) { + return reportRepository + .findByExternalId(reportId) + .orElseThrow( + () -> new NotFoundException("Report with id '%s' not found".formatted(reportId))); + } + + private void validateReportCompleted(Report report) { + if (!report.getState().equals(AggregationResultState.COMPLETED)) { + throw new BadRequestException( + "Report %s is not in state COMPLETED".formatted(report.getExternalId())); + } + } + + @Transactional + public UUID getPlannedReportToExecuteSetToPending() { + LocalDate now = LocalDate.now(clock); + + Optional<Report> reportOptional = + reportRepository.findByExecutionDateLessThanEqualAndState( + now, AggregationResultState.PLANNED); + if (reportOptional.isPresent()) { + Report report = reportOptional.get(); + report.setState(AggregationResultState.PENDING); + report.setPendingState(AggregationResultPendingState.DATA_AGGREGATION); + return report.getExternalId(); + } else { + return null; + } + } + + @Transactional + public void createNewPlannedReportInSeries(UUID reportId) { + Report report = getReportInternal(reportId); + ReportSeries reportSeries = report.getReportSeries(); + int nextNumber = getNextNumber(report); + + LocalDate executionAndEndDate = + calculateNextExecutionDate(report.getExecutionDate(), reportSeries.getFrequency()); + LocalDate dateStart = calculateStartDate(reportSeries.getPeriod(), executionAndEndDate); + + reportSeries.addReport( + createReport( + String.valueOf(nextNumber), + dateStart.atStartOfDay(clock.getZone()).toInstant(), + executionAndEndDate.atStartOfDay(clock.getZone()).toInstant(), + AggregationResultState.PLANNED, + executionAndEndDate, + reportSeries.getStatistic())); + + report.setExecutionDate(LocalDate.now(clock)); + } + + static LocalDate calculateStartDate(ReportingPeriod reportingPeriod, LocalDate executionDate) { + return switch (reportingPeriod) { + case MONTH -> executionDate.minusMonths(1); + case THREE_MONTHS -> executionDate.minusMonths(3); + case HALF_YEAR -> executionDate.minusMonths(6); + case YEAR -> executionDate.minusMonths(12); + }; + } + + private static LocalDate calculateNextExecutionDate( + LocalDate currentExecutionDate, Frequency frequency) { + return switch (frequency) { + case PER_MONTH -> currentExecutionDate.plusMonths(1); + case PER_THREE_MONTHS -> currentExecutionDate.plusMonths(3); + case PER_HALF_YEAR -> currentExecutionDate.plusMonths(6); + case PER_YEAR -> currentExecutionDate.plusMonths(12); + }; + } + + private int getNextNumber(Report report) { + try { + return Integer.parseInt(report.getName()) + 1; + } catch (NumberFormatException e) { + log.error( + "Report {} has name '{}' which is not a number", + report.getExternalId(), + report.getName()); + return report.getReportSeries().getReports().size() + 1; + } + } + + @Transactional(readOnly = true) + public ReportStateInformation getReportStateInformation(UUID reportId) { + Report report = getReportInternal(reportId); + return new ReportStateInformation(report.getState(), report.getPendingState()); + } + + @Transactional + public void aggregateData(UUID reportId) { + Report report = getReportInternal(reportId); + if (wrongConstellationForMethod( + report, AggregationResultPendingState.DATA_AGGREGATION, "aggregateData")) { + return; + } + + try { + dataAggregationService.collectTableRows(report); + } catch (Exception exception) { + log.error("Error while collecting table rows", exception); + report.setState(AggregationResultState.FAILED); + } + } + + @Transactional + public void minMaxDetermination(UUID reportId) { + Report report = getReportInternal(reportId); + if (wrongConstellationForMethod( + report, AggregationResultPendingState.MIN_MAX_DETERMINATION, "minMaxDetermination")) { + return; + } + + dataAggregationService.determineMinMaxNullUnknownValues(report); + report.setPendingState(AggregationResultPendingState.EVALUATION_CONDUCTION); + } + + @Transactional + public void evaluationConduction(UUID reportId) { + Report report = getReportInternal(reportId); + if (wrongConstellationForMethod( + report, AggregationResultPendingState.EVALUATION_CONDUCTION, "evaluationConduction")) { + return; + } + + Statistic statistic = report.getReportSeries().getStatistic(); + if (StatisticService.hasNoDiagrams(statistic)) { + finishReport(report); + } else { + copyEvaluationsWithoutDiagrams(report, statistic); + report.setPendingState(AggregationResultPendingState.DIAGRAM_CREATION); + } + } + + private void copyEvaluationsWithoutDiagrams(Report report, Statistic statistic) { + statistic.getEvaluations().stream() + .filter(evaluation -> !evaluation.getDiagrams().isEmpty()) + .forEach( + evaluation -> report.addEvaluation(copyEvaluationWithoutDiagrams(evaluation, report))); + } + + private Evaluation copyEvaluationWithoutDiagrams(Evaluation original, Report report) { + ChartConfiguration originalChartConfiguration = + Hibernate.unproxy(original.getChartConfiguration(), ChartConfiguration.class); + ChartConfiguration chartConfiguration = + StatisticCopyService.copyChartConfiguration(originalChartConfiguration, false); + + if (chartConfiguration instanceof HistogramChartConfiguration histogramChartConfiguration) { + HistogramChartConfigurationDto chartConfigurationDto = + EvaluationMapper.mapToHistogramChartConfigurationDto(histogramChartConfiguration); + histogramChartConfiguration.addBins( + evaluationService.calculateHistogramBins(chartConfigurationDto, report)); + } + + Evaluation evaluation = new Evaluation(); + evaluation.setOriginalEvaluationId(original.getExternalId()); + evaluation.setName(original.getName()); + evaluation.setChartConfiguration(chartConfiguration); + return evaluation; + } + + @Transactional + public Map<EvaluationDto, AddDiagramRequest> findMissingDiagramOrCompleteAutoReport( + UUID reportId) { + Report report = getReportInternal(reportId); + return findMissingDiagramOrComplete(report); + } + + Map<EvaluationDto, AddDiagramRequest> findMissingDiagramOrComplete(Report report) { + if (wrongConstellationForMethod( + report, AggregationResultPendingState.DIAGRAM_CREATION, "findMissingDiagramOrComplete")) { + return Collections.emptyMap(); + } + + Optional<Evaluation> firstUnfinishedEvaluation = + report.getEvaluations().stream() + .filter(evaluation -> evaluation.getOriginalEvaluationId() != null) + .findFirst(); + if (firstUnfinishedEvaluation.isEmpty()) { + finishReport(report); + return Collections.emptyMap(); + } + + Evaluation evaluationToComplete = firstUnfinishedEvaluation.get(); + + Optional<Diagram> diagramToCopyOptional = Optional.empty(); + try { + Evaluation originalEvaluation = + evaluationService.getEvaluationInternal(evaluationToComplete.getOriginalEvaluationId()); + diagramToCopyOptional = + originalEvaluation.getDiagrams().stream() + .filter(diagram -> notAlreadyCopied(evaluationToComplete, diagram)) + .findFirst(); + } catch (NotFoundException e) { + // Evaluation deleted + log.warn( + "Could not finish diagrams for report %s, evaluation %s: %s" + .formatted( + report.getExternalId(), evaluationToComplete.getExternalId(), e.getMessage())); + } + if (diagramToCopyOptional.isEmpty()) { + evaluationToComplete.setOriginalEvaluationId(null); + return Collections.emptyMap(); + } + + Diagram diagramToCopy = diagramToCopyOptional.get(); + return Map.of( + EvaluationMapper.mapToApi(evaluationToComplete, true), + new AddDiagramRequest( + diagramToCopy.getTitle(), + diagramToCopy.getDescription(), + FilterParameterMapper.mapToApi(diagramToCopy.getFilters()))); + } + + private boolean notAlreadyCopied(Evaluation evaluationToComplete, Diagram diagram) { + return evaluationToComplete.getDiagrams().stream() + .noneMatch(copiedDiagram -> isIdentical(copiedDiagram, diagram)); + } + + private boolean isIdentical(Diagram copiedDiagram, Diagram originalDiagram) { + return copiedDiagram.getTitle().equals(originalDiagram.getTitle()) + && Objects.equals(copiedDiagram.getDescription(), originalDiagram.getDescription()) + && identicalFilters( + FilterParameterMapper.mapToApi(copiedDiagram.getFilters()), + FilterParameterMapper.mapToApi(originalDiagram.getFilters())); + } + + private boolean identicalFilters( + List<TableColumnFilterParameter> copiedColumnFilters, + List<TableColumnFilterParameter> originalTableColumnFilters) { + if (copiedColumnFilters.size() != originalTableColumnFilters.size()) { + return false; + } + + return copiedColumnFilters.stream() + .allMatch( + columnFilter -> + identicalColumnFilterPresent(columnFilter, originalTableColumnFilters)) + && originalTableColumnFilters.stream() + .allMatch( + columnFilter -> identicalColumnFilterPresent(columnFilter, copiedColumnFilters)); + } + + private boolean identicalColumnFilterPresent( + TableColumnFilterParameter columnFilterToFind, List<TableColumnFilterParameter> filters) { + return filters.stream().anyMatch(filter -> isIdentical(filter, columnFilterToFind)); + } + + private boolean isIdentical( + TableColumnFilterParameter filter, TableColumnFilterParameter columnFilterToFind) { + if (!filter.type().equals(columnFilterToFind.type()) + || !filter + .attribute() + .businessModuleName() + .equals(columnFilterToFind.attribute().businessModuleName()) + || !filter.attribute().dataSourceId().equals(columnFilterToFind.attribute().dataSourceId()) + || !filter + .attribute() + .businessModuleAttributeCode() + .equals(columnFilterToFind.attribute().businessModuleAttributeCode()) + || !Objects.equals( + filter.attribute().baseModuleAttributeCode(), + columnFilterToFind.attribute().baseModuleAttributeCode())) { + return false; + } + return switch (filter) { + case BooleanFilterParameterDto booleanFilter: + { + BooleanFilterParameterDto otherFilter = (BooleanFilterParameterDto) columnFilterToFind; + yield booleanFilter.searchForTrue() == otherFilter.searchForTrue() + && booleanFilter.searchForFalse() == otherFilter.searchForFalse() + && booleanFilter.searchForNull() == otherFilter.searchForNull(); + } + case DecimalRangeFilterParameterDto decimalRangeFilter: + { + DecimalRangeFilterParameterDto otherFilter = + (DecimalRangeFilterParameterDto) columnFilterToFind; + yield decimalRangeFilter.minValueInclusive().compareTo(otherFilter.minValueInclusive()) + == 0 + && decimalRangeFilter.maxValueInclusive().compareTo(otherFilter.maxValueInclusive()) + == 0 + && decimalRangeFilter.withNullValues() == otherFilter.withNullValues(); + } + case DecimalValueFilterParameterDto decimalValueFilter: + { + DecimalValueFilterParameterDto otherFilter = + (DecimalValueFilterParameterDto) columnFilterToFind; + yield decimalValueFilter.value().compareTo(otherFilter.value()) == 0 + && decimalValueFilter.numericComparison().equals(otherFilter.numericComparison()) + && decimalValueFilter.withNullValues() == otherFilter.withNullValues(); + } + case IntegerRangeFilterParameterDto integerRangeFilter: + { + IntegerRangeFilterParameterDto otherFilter = + (IntegerRangeFilterParameterDto) columnFilterToFind; + yield integerRangeFilter.minValueInclusive().equals(otherFilter.minValueInclusive()) + && integerRangeFilter.maxValueInclusive().equals(otherFilter.maxValueInclusive()) + && integerRangeFilter.withNullValues() == otherFilter.withNullValues(); + } + case IntegerValueFilterParameterDto integerValueFilter: + { + IntegerValueFilterParameterDto otherFilter = + (IntegerValueFilterParameterDto) columnFilterToFind; + yield integerValueFilter.value().equals(otherFilter.value()) + && integerValueFilter.numericComparison().equals(otherFilter.numericComparison()) + && integerValueFilter.withNullValues() == otherFilter.withNullValues(); + } + case NullFilterParameterDto ignored: + { + yield true; + } + case TextFilterParameterDto textFilter: + { + yield textFilter.text().equals(((TextFilterParameterDto) columnFilterToFind).text()); + } + case ValueOptionFilterParameterDto valueOptionFilter: + { + ValueOptionFilterParameterDto otherFilter = + (ValueOptionFilterParameterDto) columnFilterToFind; + Set<String> searchValueSet = new HashSet<>(valueOptionFilter.searchValues()); + Set<String> otherSearchValueSet = new HashSet<>(otherFilter.searchValues()); + yield searchValueSet.containsAll(otherFilter.searchValues()) + && otherSearchValueSet.containsAll(valueOptionFilter.searchValues()) + && valueOptionFilter.searchForNull() == otherFilter.searchForNull(); + } + }; + } + + private static boolean wrongConstellationForMethod( + Report report, AggregationResultPendingState expectedPendingState, String method) { + if (!report.getState().equals(AggregationResultState.PENDING) + || !report.getPendingState().equals(expectedPendingState)) { + + log.error( + "'{}' called for wrong constellation {} {}", + method, + report.getState(), + report.getPendingState()); + report.setState(AggregationResultState.FAILED); + return true; + } + return false; + } + + private static void finishReport(Report report) { + report.setPendingState(null); + report.setState(AggregationResultState.COMPLETED); + ReportSeries reportSeries = report.getReportSeries(); + if (reportSeries.getReportType().equals(ReportType.AUTO)) { + reportSeries.setTimeRangeStart(report.getTimeRangeStart()); + reportSeries.setTimeRangeEnd(report.getTimeRangeEnd()); + } + } + + @Transactional + public void setStateToFailed(UUID reportId) { + Report report = getReportInternal(reportId); + if (!report.getState().equals(AggregationResultState.FAILED)) { + report.setState(AggregationResultState.FAILED); + } + } +} diff --git a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/StatisticController.java b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/StatisticController.java index 11fd25ef127c0755b168c1d5c6f67dbdb6e16dca..6b2d50f0dd54e604f4c2b6b9cf60da4a4fb6104d 100644 --- a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/StatisticController.java +++ b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/StatisticController.java @@ -32,6 +32,8 @@ import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; @@ -52,6 +54,8 @@ public class StatisticController { private final StatisticCopyService statisticCopyService; private final StatisticsFeatureToggle featureToggle; + private static final Logger log = LoggerFactory.getLogger(StatisticController.class); + public StatisticController( StatisticService statisticService, ModuleClientAuthenticator moduleClientAuthenticator, @@ -70,11 +74,16 @@ public class StatisticController { UUID uuid = statisticService.addStatistic(addStatisticRequest); CompletableFuture.runAsync( () -> { - while (statisticService - .getAggregationResultState(uuid) - .equals(AggregationResultState.PENDING)) { - moduleClientAuthenticator.doWithModuleClientAuthentication( - () -> statisticService.workOnPendingStatistic(uuid)); + try { + while (statisticService + .getAggregationResultState(uuid) + .equals(AggregationResultState.PENDING)) { + moduleClientAuthenticator.doWithModuleClientAuthentication( + () -> statisticService.workOnPendingStatistic(uuid)); + } + } catch (Exception e) { + log.error("Could not complete statistic", e); + setState(uuid, AggregationResultState.FAILED); } }); return uuid; @@ -90,17 +99,28 @@ public class StatisticController { CompletableFuture.runAsync( () -> { - while (statisticService - .getAggregationResultState(originalId) - .equals(AggregationResultState.COPY_ONGOING)) { - moduleClientAuthenticator.doWithModuleClientAuthentication( - () -> statisticCopyService.workOnCopy(originalId, copyId)); + try { + while (statisticService + .getAggregationResultState(originalId) + .equals(AggregationResultState.COPY_ONGOING)) { + moduleClientAuthenticator.doWithModuleClientAuthentication( + () -> statisticCopyService.workOnCopy(originalId, copyId)); + } + } catch (Exception e) { + log.error("Could not complete cloning statistic", e); + setState(originalId, AggregationResultState.COMPLETED); + setState(copyId, AggregationResultState.FAILED); } }); return copyId; } + private void setState(UUID statisticId, AggregationResultState state) { + moduleClientAuthenticator.doWithModuleClientAuthentication( + () -> statisticService.setState(statisticId, state)); + } + @GetExchange(accept = APPLICATION_JSON_VALUE) @ApiResponse(responseCode = "200", description = "All statistics") @Operation(summary = "Get all statistics") diff --git a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/StatisticService.java b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/StatisticService.java index faa7d776cb664c4023786344e552be79cace5551..225ab8edf07194fd374468abcfa53d126abc7409 100644 --- a/backend/statistics/src/main/java/de/eshg/statistics/aggregation/StatisticService.java +++ b/backend/statistics/src/main/java/de/eshg/statistics/aggregation/StatisticService.java @@ -416,4 +416,16 @@ public class StatisticService { return new GetReportSeriesEntriesOfStatisticResponse( statistic.getExternalId(), statistic.getName(), reportSeriesDtos, resolvedUsers); } + + static boolean hasNoDiagrams(Statistic statistic) { + return statistic.getEvaluations().isEmpty() + || statistic.getEvaluations().stream() + .allMatch(evaluation -> evaluation.getDiagrams().isEmpty()); + } + + @Transactional + public void setState(UUID statisticId, AggregationResultState state) { + Statistic statistic = getStatistic(statisticId); + statistic.setState(state); + } } diff --git a/backend/statistics/src/main/java/de/eshg/statistics/config/AutoReportSeriesConfig.java b/backend/statistics/src/main/java/de/eshg/statistics/config/AutoReportSeriesConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..538506b5166274d1c1f3ec5b23f8ebce1025c5de --- /dev/null +++ b/backend/statistics/src/main/java/de/eshg/statistics/config/AutoReportSeriesConfig.java @@ -0,0 +1,13 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.statistics.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; + +@Configuration +@EnableScheduling +public class AutoReportSeriesConfig {} diff --git a/backend/statistics/src/main/java/de/eshg/statistics/persistence/repository/ReportRepository.java b/backend/statistics/src/main/java/de/eshg/statistics/persistence/repository/ReportRepository.java index eca3b2833d4549a61aa233d48722c69456364369..b471d844216409e59cf7c341647c62ce6b1556cc 100644 --- a/backend/statistics/src/main/java/de/eshg/statistics/persistence/repository/ReportRepository.java +++ b/backend/statistics/src/main/java/de/eshg/statistics/persistence/repository/ReportRepository.java @@ -5,7 +5,9 @@ package de.eshg.statistics.persistence.repository; +import de.eshg.statistics.persistence.entity.AggregationResultState; import de.eshg.statistics.persistence.entity.report.Report; +import java.time.LocalDate; import java.util.Optional; import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; @@ -13,4 +15,7 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface ReportRepository extends JpaRepository<Report, Long> { Optional<Report> findByExternalId(UUID externalId); + + Optional<Report> findByExecutionDateLessThanEqualAndState( + LocalDate date, AggregationResultState state); } diff --git a/backend/statistics/src/main/java/de/eshg/statistics/testhelper/StatisticsTestHelperController.java b/backend/statistics/src/main/java/de/eshg/statistics/testhelper/StatisticsTestHelperController.java index c26a383dd839af1119861c40dcf0dfab09c026e6..87be2115be3e0dafee5656207949f2fd826e414c 100644 --- a/backend/statistics/src/main/java/de/eshg/statistics/testhelper/StatisticsTestHelperController.java +++ b/backend/statistics/src/main/java/de/eshg/statistics/testhelper/StatisticsTestHelperController.java @@ -5,14 +5,16 @@ package de.eshg.statistics.testhelper; -import de.eshg.auditlog.AuditLogTestHelperApi; +import de.eshg.auditlog.SharedAuditLogTestHelperApi; import de.eshg.lib.auditlog.AuditLogTestHelperService; +import de.eshg.statistics.aggregation.ReportExecution; import de.eshg.statistics.config.StatisticsFeature; import de.eshg.statistics.config.StatisticsFeatureToggle; import de.eshg.testhelper.ConditionalOnTestHelperEnabled; import de.eshg.testhelper.DefaultTestHelperService; import de.eshg.testhelper.TestHelperController; import java.io.IOException; +import java.util.concurrent.CompletableFuture; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.service.annotation.PostExchange; @@ -20,18 +22,21 @@ import org.springframework.web.service.annotation.PostExchange; @RestController @ConditionalOnTestHelperEnabled public class StatisticsTestHelperController extends TestHelperController - implements AuditLogTestHelperApi { + implements SharedAuditLogTestHelperApi { private final StatisticsFeatureToggle statisticsFeatureToggle; private final AuditLogTestHelperService auditLogTestHelperService; + private final ReportExecution reportExecution; public StatisticsTestHelperController( StatisticsFeatureToggle statisticsFeatureToggle, DefaultTestHelperService testHelperService, - AuditLogTestHelperService auditLogTestHelperService) { + AuditLogTestHelperService auditLogTestHelperService, + ReportExecution reportExecution) { super(testHelperService); this.statisticsFeatureToggle = statisticsFeatureToggle; this.auditLogTestHelperService = auditLogTestHelperService; + this.reportExecution = reportExecution; } @PostExchange("/enabled-new-features/{featureToEnable}") @@ -39,6 +44,11 @@ public class StatisticsTestHelperController extends TestHelperController statisticsFeatureToggle.enableNewFeature(featureToEnable); } + @PostExchange("/finish-auto-reports") + public void finishAutoReports() { + CompletableFuture.runAsync(reportExecution::handlePlannedReports); + } + @Override public void clearAuditLogStorageDirectory() throws IOException { auditLogTestHelperService.clearAuditLogStorageDirectory(); diff --git a/backend/statistics/src/main/resources/application-preview-features.properties b/backend/statistics/src/main/resources/application-preview-features.properties index 67510d9e3e1252bb4e7bd98c337faa8e37d670c7..a880a131c4863aab1dcee4e43668bb7b69c93453 100644 --- a/backend/statistics/src/main/resources/application-preview-features.properties +++ b/backend/statistics/src/main/resources/application-preview-features.properties @@ -1 +1 @@ -de.eshg.statistics.feature-toggle.enabled-new-features=CLONE_STATISTIC +de.eshg.statistics.feature-toggle.enabled-new-features=CLONE_STATISTIC, REPORTS diff --git a/backend/sti-protection/gradle.lockfile b/backend/sti-protection/gradle.lockfile index a8d34ff4bf9c660455d7684fc18bc8d219c9fb3e..c67d7812f81b469b5f317f9d70cfad3e0a5ebed1 100644 --- a/backend/sti-protection/gradle.lockfile +++ b/backend/sti-protection/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.adobe.xmp:xmpcore:6.1.11=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.drewnoakes:metadata-extractor:2.19.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -25,8 +25,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -43,9 +44,9 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath commons-logging:commons-logging:1.3.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -53,11 +54,11 @@ de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -65,14 +66,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -106,10 +106,10 @@ org.apache.tika:tika-bom:2.9.2=productionRuntimeClasspath,runtimeClasspath,testR org.apache.tika:tika-core:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-pdf-module:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-xmp-commons:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.aspectj:aspectjweaver:1.9.22.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath @@ -128,9 +128,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -157,7 +157,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -165,30 +165,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -198,19 +198,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/sti-protection/openApi.yaml b/backend/sti-protection/openApi.yaml index d21611c9bc8e9983f0364f1dab5a2978ce86078e..b0e33538b45c59523331ea4a2346870e181ab6c4 100644 --- a/backend/sti-protection/openApi.yaml +++ b/backend/sti-protection/openApi.yaml @@ -1995,8 +1995,12 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 required: - assignee + - taskVersion BulkUpdateProceduresArchivingRelevanceRequest: type: object properties: @@ -2999,7 +3003,7 @@ components: - totalPages GetArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - PROCEDURE_TYPE @@ -3258,7 +3262,7 @@ components: - totalPages GetRelevantArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - EXPORTED_AT @@ -4091,6 +4095,11 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 + required: + - taskVersion SortDirection: type: string enum: @@ -4223,6 +4232,9 @@ components: $ref: "#/components/schemas/TaskStatus" taskType: $ref: "#/components/schemas/TaskType" + version: + type: integer + format: int64 required: - businessModule - createdAt @@ -4233,6 +4245,7 @@ components: - taskId - taskStatus - taskType + - version TaskMetric: type: object properties: diff --git a/backend/sti-protection/src/main/java/de/eshg/stiprotection/api/CreateProcedureRequest.java b/backend/sti-protection/src/main/java/de/eshg/stiprotection/api/CreateProcedureRequest.java index ee9140b02baadfe9ee0a01bb795136df5fc1b2f1..7cca71b675e97de67b123557babc0e28f78c5dd4 100644 --- a/backend/sti-protection/src/main/java/de/eshg/stiprotection/api/CreateProcedureRequest.java +++ b/backend/sti-protection/src/main/java/de/eshg/stiprotection/api/CreateProcedureRequest.java @@ -5,9 +5,11 @@ package de.eshg.stiprotection.api; +import com.fasterxml.jackson.annotation.JsonIgnore; import de.eshg.base.CountryCodeDto; import de.eshg.base.GenderDto; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.AssertTrue; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Past; import jakarta.validation.constraints.PastOrPresent; @@ -23,4 +25,14 @@ public record CreateProcedureRequest( description = "The year since the person has been residing in Germany.", example = "2022") @PastOrPresent - Year inGermanySince) {} + Year inGermanySince) { + @AssertTrue(message = "The year of birth must be prior to the date of residence in Germany.") + @JsonIgnore + @SuppressWarnings("unused") + public boolean isInGermanySinceValid() { + if (inGermanySince == null) { + return true; + } + return yearOfBirth.isBefore(inGermanySince); + } +} diff --git a/backend/sti-protection/src/main/java/de/eshg/stiprotection/config/StiProtectionAppointmentBlockConfiguration.java b/backend/sti-protection/src/main/java/de/eshg/stiprotection/config/StiProtectionAppointmentBlockConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..da5c2d5939d9c441ab2e13806c5bbeb7220e2443 --- /dev/null +++ b/backend/sti-protection/src/main/java/de/eshg/stiprotection/config/StiProtectionAppointmentBlockConfiguration.java @@ -0,0 +1,30 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.stiprotection.config; + +import de.eshg.lib.appointmentblock.AppointmentBlockService; +import de.eshg.lib.keycloak.TechnicalGroup; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class StiProtectionAppointmentBlockConfiguration { + + @Bean(name = AppointmentBlockService.TECHNICAL_GROUP_PHYSICIANS) + TechnicalGroup technicalGroupPhysicians() { + return TechnicalGroup.STI_PROTECTION_PHYSICIANS; + } + + @Bean(name = AppointmentBlockService.TECHNICAL_GROUP_MFAS) + TechnicalGroup technicalGroupMfas() { + return TechnicalGroup.STI_PROTECTION_MFAS; + } + + @Bean(name = AppointmentBlockService.TECHNICAL_GROUP_CONSULTANTS) + TechnicalGroup technicalGroupConsultants() { + return TechnicalGroup.STI_PROTECTION_CONSULTANTS; + } +} diff --git a/backend/sti-protection/src/main/java/de/eshg/stiprotection/persistence/db/Person.java b/backend/sti-protection/src/main/java/de/eshg/stiprotection/persistence/db/Person.java index 59ce42b3fee9346f210bff4b0d8ab5b830108356..c0e557bd336b390e98674e7b78c2e03e37b9e838 100644 --- a/backend/sti-protection/src/main/java/de/eshg/stiprotection/persistence/db/Person.java +++ b/backend/sti-protection/src/main/java/de/eshg/stiprotection/persistence/db/Person.java @@ -18,7 +18,7 @@ import org.hibernate.annotations.JdbcType; import org.hibernate.dialect.PostgreSQLEnumJdbcType; @Entity -@Table(indexes = @Index(columnList = "procedure_id")) +@Table(indexes = @Index(columnList = "procedure_id", unique = true)) public class Person extends RelatedPerson<StiProtectionProcedure> { @JdbcType(PostgreSQLEnumJdbcType.class) diff --git a/backend/sti-protection/src/main/java/de/eshg/stiprotection/testhelper/StiProtectionTestHelperController.java b/backend/sti-protection/src/main/java/de/eshg/stiprotection/testhelper/StiProtectionTestHelperController.java index 826e1e571caa015553d4e375bccd461983f9d96e..12e3a647d6ef149604f240f3b721da07e8d49ea2 100644 --- a/backend/sti-protection/src/main/java/de/eshg/stiprotection/testhelper/StiProtectionTestHelperController.java +++ b/backend/sti-protection/src/main/java/de/eshg/stiprotection/testhelper/StiProtectionTestHelperController.java @@ -5,14 +5,13 @@ package de.eshg.stiprotection.testhelper; -import de.eshg.auditlog.AuditLogTestHelperApi; +import de.eshg.auditlog.SharedAuditLogTestHelperApi; import de.eshg.lib.auditlog.AuditLogTestHelperService; import de.eshg.stiprotection.api.CreateProcedureResponse; import de.eshg.stiprotection.api.StiProtectionProcedurePopulationRequest; import de.eshg.stiprotection.api.StiProtectionProcedurePopulationResponse; import de.eshg.testhelper.ConditionalOnTestHelperEnabled; import de.eshg.testhelper.TestHelperController; -import de.eshg.testhelper.TestHelperService; import de.eshg.testhelper.population.ListWithTotalNumber; import jakarta.validation.Valid; import java.io.IOException; @@ -23,13 +22,13 @@ import org.springframework.web.service.annotation.PostExchange; @RestController @ConditionalOnTestHelperEnabled public class StiProtectionTestHelperController extends TestHelperController - implements AuditLogTestHelperApi { + implements SharedAuditLogTestHelperApi { private final AuditLogTestHelperService auditLogTestHelperService; private final StiProtectionPopulator populator; public StiProtectionTestHelperController( - TestHelperService testHelperService, + StiProtectionTestHelperService testHelperService, AuditLogTestHelperService auditLogTestHelperService, StiProtectionPopulator populator) { super(testHelperService); diff --git a/backend/sti-protection/src/main/java/de/eshg/stiprotection/testhelper/StiProtectionTestHelperService.java b/backend/sti-protection/src/main/java/de/eshg/stiprotection/testhelper/StiProtectionTestHelperService.java new file mode 100644 index 0000000000000000000000000000000000000000..78c0dee3a01b963cc75f242e95ea6893ca6596cc --- /dev/null +++ b/backend/sti-protection/src/main/java/de/eshg/stiprotection/testhelper/StiProtectionTestHelperService.java @@ -0,0 +1,44 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package de.eshg.stiprotection.testhelper; + +import de.eshg.lib.appointmentblock.persistence.CreateAppointmentTypeTask; +import de.eshg.testhelper.ConditionalOnTestHelperEnabled; +import de.eshg.testhelper.DatabaseResetHelper; +import de.eshg.testhelper.DefaultTestHelperService; +import de.eshg.testhelper.ResettableProperties; +import de.eshg.testhelper.interception.TestRequestInterceptor; +import de.eshg.testhelper.population.BasePopulator; +import java.sql.SQLException; +import java.time.Clock; +import java.time.Instant; +import java.util.List; +import org.springframework.stereotype.Service; + +@ConditionalOnTestHelperEnabled +@Service +public class StiProtectionTestHelperService extends DefaultTestHelperService { + + private final CreateAppointmentTypeTask createAppointmentTypeTask; + + public StiProtectionTestHelperService( + DatabaseResetHelper databaseResetHelper, + TestRequestInterceptor testRequestInterceptor, + Clock clock, + List<BasePopulator<?>> populators, + List<ResettableProperties> resettableProperties, + CreateAppointmentTypeTask createAppointmentTypeTask) { + super(databaseResetHelper, testRequestInterceptor, clock, populators, resettableProperties); + this.createAppointmentTypeTask = createAppointmentTypeTask; + } + + @Override + public Instant reset() throws SQLException { + Instant newInstant = super.reset(); + createAppointmentTypeTask.createAppointmentTypes(); + return newInstant; + } +} diff --git a/backend/sti-protection/src/main/resources/application.properties b/backend/sti-protection/src/main/resources/application.properties index dd711bd08c3aac00f924b3157085d71dfdebaae8..e78d5f8a917b78b445164f1b7489e0836eeacca8 100644 --- a/backend/sti-protection/src/main/resources/application.properties +++ b/backend/sti-protection/src/main/resources/application.properties @@ -14,5 +14,8 @@ spring.security.oauth2.client.registration.module-client.client-id=system-sti-pr spring.security.oauth2.client.registration.module-client.client-secret=password spring.security.oauth2.client.provider.eshg-keycloak.token-uri=${eshg.keycloak.internal.url}/realms/eshg/protocol/openid-connect/token -de.eshg.lib.appointmentblock.defaultAppointmentTypeConfiguration[CONSULTATION]=10m +de.eshg.lib.appointmentblock.defaultAppointmentTypeConfiguration[HIV_STI_CONSULTATION]=30m +de.eshg.lib.appointmentblock.defaultAppointmentTypeConfiguration[SEX_WORK]=30m +de.eshg.lib.appointmentblock.defaultAppointmentTypeConfiguration[RESULTS_REVIEW]=30m + eshg.population.sti-protection-procedure=30 diff --git a/backend/sti-protection/src/main/resources/migrations/00003_unique_constraint_person_procedure_id_key.xml b/backend/sti-protection/src/main/resources/migrations/00003_unique_constraint_person_procedure_id_key.xml new file mode 100644 index 0000000000000000000000000000000000000000..dfcaa5926c591bead46bb58be3fcdd056985d830 --- /dev/null +++ b/backend/sti-protection/src/main/resources/migrations/00003_unique_constraint_person_procedure_id_key.xml @@ -0,0 +1,19 @@ +<?xml version="1.1" encoding="UTF-8" standalone="no"?> +<!-- + Copyright 2024 cronn GmbH + SPDX-License-Identifier: AGPL-3.0-only +--> + +<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"> + <changeSet author="GA-Lotse" id="1727187220306-3"> + <addUniqueConstraint columnNames="procedure_id" constraintName="person_procedure_id_key" tableName="person"/> + </changeSet> + <changeSet author="GA-Lotse" id="1727187220306-1"> + <dropUniqueConstraint constraintName="person_procedure_id_key" tableName="person"/> + </changeSet> + <changeSet author="GA-Lotse" id="1727187220306-2"> + <addUniqueConstraint columnNames="procedure_id" constraintName="person_procedure_id_key" tableName="person"/> + </changeSet> +</databaseChangeLog> diff --git a/backend/sti-protection/src/main/resources/migrations/changelog.xml b/backend/sti-protection/src/main/resources/migrations/changelog.xml index 9ca056334ee5e3fe657bebfb65f80837d9397db9..53c604b35a86288da6a28e7d496858b16c284c4f 100644 --- a/backend/sti-protection/src/main/resources/migrations/changelog.xml +++ b/backend/sti-protection/src/main/resources/migrations/changelog.xml @@ -10,5 +10,6 @@ <include file="migrations/0001_initial.xml"/> <include file="migrations/0002_procedure_sequences.xml"/> + <include file="migrations/00003_unique_constraint_person_procedure_id_key.xml"/> </databaseChangeLog> diff --git a/backend/test-commons/gradle.lockfile b/backend/test-commons/gradle.lockfile index 4419a31333519a3967ea6ac8ae2fdf582e00527f..1e2d83439d7b09422f138a92cfed55600ad0f1af 100644 --- a/backend/test-commons/gradle.lockfile +++ b/backend/test-commons/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -16,8 +16,9 @@ com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.9.2=compileClass com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.sun.istack:istack-commons-runtime:4.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -27,15 +28,15 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=productionRuntimeClasspath,run com.tngtech.archunit:archunit-junit5:1.3.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -69,7 +70,7 @@ org.glassfish.jaxb:txw2:4.0.5=productionRuntimeClasspath,runtimeClasspath,testRu org.hamcrest:hamcrest-core:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt @@ -91,29 +92,29 @@ org.opentest4j:opentest4j:1.3.0=compileClasspath,productionRuntimeClasspath,runt org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.19.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath diff --git a/backend/test-commons/src/main/java/de/eshg/base/logging/CapturedLoggingTraits.java b/backend/test-commons/src/main/java/de/eshg/base/logging/CapturedLoggingTraits.java index 8f8b5d5e7903ecf44895ac0e2a5bbf43353c9d84..a56f0c92e93cb049c7e3f24681592d9ac33c6538 100644 --- a/backend/test-commons/src/main/java/de/eshg/base/logging/CapturedLoggingTraits.java +++ b/backend/test-commons/src/main/java/de/eshg/base/logging/CapturedLoggingTraits.java @@ -92,25 +92,17 @@ public interface CapturedLoggingTraits extends JUnit5ValidationFileAssertions { throws Exception { RenderingOptions renderingOptions = new RenderingOptions(true, 40, true); - // Spring’s DispatcherServlet logs some messages when it is lazily initialized upon receiving - // the first REST call. - // Unfortunately, this results in non-deterministic log outputs in our validation files. - // Therefore, we filter it out by default. - EventFilter defaultEventFilter = - event -> - !isDispatcherServletInitializationLogging(event) - && !event - .getFormattedMessage() - .contains( - "Reached the maximum number of URI tags for 'http.client.requests'. Are you using 'uriVariables'?"); + EventFilter defaultEventFilter = capturedLoggingDefaultEventFilter(); EventFilter eventFilter = defaultEventFilter.and(additionalFilter); + beforeCapturedConsoleLogging(); + try (CapturingAppender appender = CapturingAppender.create( Logger.ROOT_LOGGER_NAME, renderingOptions, eventFilter, logLevel)) { try { - return callable.call(); + return executeForCapturedConsoleLogging(callable); } finally { String events = appender.renderEvents().collect(Collectors.joining("\n")); assertWithFileWithSuffix(events, validationNormalizer, suffix); @@ -118,6 +110,31 @@ public interface CapturedLoggingTraits extends JUnit5ValidationFileAssertions { } } + default void beforeCapturedConsoleLogging() throws Exception {} + + default <T> T executeForCapturedConsoleLogging(Callable<T> callable) throws Exception { + return callable.call(); + } + + /* Spring’s DispatcherServlet logs some messages when it is lazily initialized upon receiving + * the first REST call. + * Unfortunately, this results in non-deterministic log outputs in our validation files. + * Therefore, we filter it out by default. + */ + default EventFilter capturedLoggingDefaultEventFilter() { + EventFilter excludeDispatcherServlet = + event -> !isDispatcherServletInitializationLogging(event); + + EventFilter excludeMaxHttpClientRequestsWarning = + event -> + !event + .getFormattedMessage() + .contains( + "Reached the maximum number of URI tags for 'http.client.requests'. Are you using 'uriVariables'?"); + + return excludeDispatcherServlet.and(excludeMaxHttpClientRequestsWarning); + } + private static boolean isDispatcherServletInitializationLogging(ILoggingEvent event) { String formattedMessage = event.getFormattedMessage(); if (formattedMessage.contains("Initializing Spring DispatcherServlet")) { diff --git a/backend/test-commons/src/main/java/de/eshg/normalization/SimpleContentLengthReplacement.java b/backend/test-commons/src/main/java/de/eshg/normalization/SimpleContentLengthReplacement.java new file mode 100644 index 0000000000000000000000000000000000000000..b66c363a8cc1f27c1138fc43d34ade80759d5528 --- /dev/null +++ b/backend/test-commons/src/main/java/de/eshg/normalization/SimpleContentLengthReplacement.java @@ -0,0 +1,15 @@ +/* + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.eshg.normalization; + +import de.cronn.assertions.validationfile.normalization.SimpleRegexReplacement; + +public class SimpleContentLengthReplacement extends SimpleRegexReplacement { + + public SimpleContentLengthReplacement() { + super("Content-Length: \\[\\d*\\]", "Content-Length: [LENGTH]"); + } +} diff --git a/backend/test-helper-commons-api/gradle.lockfile b/backend/test-helper-commons-api/gradle.lockfile index 06dbb2ff09463c86d7b0f212437a6699ede95eaf..8017562d7c3154dd506763857adba48e3e63daef 100644 --- a/backend/test-helper-commons-api/gradle.lockfile +++ b/backend/test-helper-commons-api/gradle.lockfile @@ -1,15 +1,15 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson:jackson-bom:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -46,21 +46,21 @@ org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/test-helper-commons-spring/README_LICENSE.adoc b/backend/test-helper-commons-spring/README_LICENSE.adoc new file mode 100644 index 0000000000000000000000000000000000000000..87f2419aaf60835f287ea4b3d058bd1a2cd01097 --- /dev/null +++ b/backend/test-helper-commons-spring/README_LICENSE.adoc @@ -0,0 +1,5 @@ +== Licensing + +All files within this directory, including those in all subdirectories, are licensed under the Apache License 2.0. + +For the complete license text, please refer to the `LICENSE-APACHE-2.0.txt` file located in the project root. diff --git a/backend/test-helper-commons-spring/build.gradle b/backend/test-helper-commons-spring/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..c046384d47380346071e9ab99a566367c39f2f78 --- /dev/null +++ b/backend/test-helper-commons-spring/build.gradle @@ -0,0 +1,7 @@ +plugins { + id "eshg.java-lib" +} + +dependencies { + implementation 'org.springframework:spring-context' +} diff --git a/backend/test-helper-commons-spring/buildscript-gradle.lockfile b/backend/test-helper-commons-spring/buildscript-gradle.lockfile new file mode 100644 index 0000000000000000000000000000000000000000..0d156738b209adc7660610a8d35b7e87ebdb8211 --- /dev/null +++ b/backend/test-helper-commons-spring/buildscript-gradle.lockfile @@ -0,0 +1,4 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +empty=classpath diff --git a/backend/test-helper-commons-spring/gradle.lockfile b/backend/test-helper-commons-spring/gradle.lockfile new file mode 100644 index 0000000000000000000000000000000000000000..89f7ac29a7c70c1418cc2ab519def8e652e960d4 --- /dev/null +++ b/backend/test-helper-commons-spring/gradle.lockfile @@ -0,0 +1,61 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath +com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath +com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath +jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath +jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=testCompileClasspath,testRuntimeClasspath +net.bytebuddy:byte-buddy-agent:1.14.19=testCompileClasspath,testRuntimeClasspath +net.bytebuddy:byte-buddy:1.14.19=testCompileClasspath,testRuntimeClasspath +net.minidev:accessors-smart:2.5.1=testCompileClasspath,testRuntimeClasspath +net.minidev:json-smart:2.5.1=testCompileClasspath,testRuntimeClasspath +org.apache.logging.log4j:log4j-api:2.23.1=testCompileClasspath,testRuntimeClasspath +org.apache.logging.log4j:log4j-to-slf4j:2.23.1=testCompileClasspath,testRuntimeClasspath +org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath +org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath +org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath +org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath +org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt +org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt +org.jacoco:org.jacoco.core:0.8.11=jacocoAnt +org.jacoco:org.jacoco.report:0.8.11=jacocoAnt +org.junit.jupiter:junit-jupiter-api:5.10.3=testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter-engine:5.10.3=testRuntimeClasspath +org.junit.jupiter:junit-jupiter-params:5.10.3=testCompileClasspath,testRuntimeClasspath +org.junit.jupiter:junit-jupiter:5.10.3=testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-commons:1.10.3=testCompileClasspath,testRuntimeClasspath +org.junit.platform:junit-platform-engine:1.10.3=testRuntimeClasspath +org.junit.platform:junit-platform-launcher:1.10.3=testRuntimeClasspath +org.junit:junit-bom:5.10.3=testCompileClasspath,testRuntimeClasspath +org.mockito:mockito-core:5.11.0=testCompileClasspath,testRuntimeClasspath +org.mockito:mockito-junit-jupiter:5.11.0=testCompileClasspath,testRuntimeClasspath +org.objenesis:objenesis:3.3=testRuntimeClasspath +org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath +org.ow2.asm:asm-commons:9.6=jacocoAnt +org.ow2.asm:asm-tree:9.6=jacocoAnt +org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath +org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath +org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath +org.slf4j:slf4j-api:2.0.16=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath +org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath +empty=annotationProcessor,developmentOnly,testAndDevelopmentOnly,testAnnotationProcessor,testFixturesCompileClasspath,testFixturesRuntimeClasspath diff --git a/backend/test-helper-commons/src/main/java/de/eshg/testhelper/ConditionalOnTestHelperEnabled.java b/backend/test-helper-commons-spring/src/main/java/de/eshg/testhelper/ConditionalOnTestHelperEnabled.java similarity index 100% rename from backend/test-helper-commons/src/main/java/de/eshg/testhelper/ConditionalOnTestHelperEnabled.java rename to backend/test-helper-commons-spring/src/main/java/de/eshg/testhelper/ConditionalOnTestHelperEnabled.java diff --git a/backend/test-helper-commons/build.gradle b/backend/test-helper-commons/build.gradle index 21f5ac258c8c6db1febb2a9a59083892a84bfb3c..759414d7800c2a58abd3e8744bb8414a4f8f1cfb 100644 --- a/backend/test-helper-commons/build.gradle +++ b/backend/test-helper-commons/build.gradle @@ -4,7 +4,7 @@ plugins { dependencies { api 'de.cronn:commons-lang:latest.release' - implementation 'org.springframework:spring-context' + api project(':test-helper-commons-spring') implementation 'org.springframework:spring-tx' implementation 'org.springframework.boot:spring-boot-autoconfigure' implementation 'org.springframework.security:spring-security-oauth2-jose' @@ -27,5 +27,6 @@ dependencies { api 'net.datafaker:datafaker:latest.release' testImplementation project(':business-module-commons') + testImplementation project(':rest-service-commons') testImplementation testFixtures(project(':business-module-commons')) } diff --git a/backend/test-helper-commons/gradle.lockfile b/backend/test-helper-commons/gradle.lockfile index f52d037dddc7f5609f758f19413d56776a844737..571c853a2602e617e5aaf3ff5673ed1b039fa201 100644 --- a/backend/test-helper-commons/gradle.lockfile +++ b/backend/test-helper-commons/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -22,8 +22,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath @@ -35,17 +36,17 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:reflection-util:2.17.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=testRuntimeClasspath @@ -53,14 +54,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=testRuntimeClasspath io.smallrye:jandex:3.1.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -80,10 +80,10 @@ org.apache.httpcomponents.core5:httpcore5-h2:5.2.5=testRuntimeClasspath org.apache.httpcomponents.core5:httpcore5:5.2.5=testRuntimeClasspath org.apache.logging.log4j:log4j-api:2.23.1=testCompileClasspath,testRuntimeClasspath org.apache.logging.log4j:log4j-to-slf4j:2.23.1=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.25.3=testCompileClasspath,testRuntimeClasspath org.awaitility:awaitility:4.2.2=testCompileClasspath,testRuntimeClasspath @@ -99,7 +99,7 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.hibernate.validator:hibernate-validator:8.0.1.Final=testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -124,7 +124,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath @@ -132,25 +132,25 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -159,16 +159,16 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=testCompileClasspath,testRuntimeClasspath org.testcontainers:testcontainers:1.19.8=testCompileClasspath,testRuntimeClasspath org.webjars:swagger-ui:5.17.14=testCompileClasspath,testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath diff --git a/backend/travel-medicine/gradle.lockfile b/backend/travel-medicine/gradle.lockfile index 41d92e96882f581906cb22b2d61c772440dca3f3..15d72a8ac0b2992920aa2f0985a5885b6ce090ee 100644 --- a/backend/travel-medicine/gradle.lockfile +++ b/backend/travel-medicine/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.adobe.xmp:xmpcore:6.1.11=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.drewnoakes:metadata-extractor:2.19.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -25,8 +25,9 @@ com.github.stephenc.jcip:jcip-annotations:1.0-1=compileClasspath,productionRunti com.google.code.findbugs:jsr305:3.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +com.google.j2objc:j2objc-annotations:3.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.googlecode.libphonenumber:libphonenumber:8.13.41=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -43,9 +44,9 @@ com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath com.zaxxer:HikariCP:5.1.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath commons-logging:commons-logging:1.3.3=productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator-postgresql:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-changelog-generator:1.0=testCompileClasspath,testRuntimeClasspath de.cronn:liquibase-postgres-enum-extension:1.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -58,11 +59,11 @@ io.github.openhtmltopdf:openhtmltopdf-core:1.1.22=productionRuntimeClasspath,run io.github.openhtmltopdf:openhtmltopdf-pdfbox:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-slf4j:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.github.openhtmltopdf:openhtmltopdf-svg-support:1.1.22=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-core:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-jakarta9:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-registry-prometheus:1.13.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-core:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-jakarta9:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-registry-prometheus:1.13.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-config:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-core:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-exposition-formats:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -70,14 +71,13 @@ io.prometheus:prometheus-metrics-model:1.2.1=productionRuntimeClasspath,runtimeC io.prometheus:prometheus-metrics-shaded-protobuf:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.prometheus:prometheus-metrics-tracer-common:1.2.1=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-core-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.swagger.core.v3:swagger-models-jakarta:2.2.22=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.persistence:jakarta.persistence-api:3.1.0=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -jakarta.servlet:jakarta.servlet-api:6.0.0=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.1=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.validation:jakarta.validation-api:3.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath jakarta.xml.bind:jakarta.xml.bind-api:4.0.2=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -112,10 +112,10 @@ org.apache.tika:tika-bom:2.9.2=productionRuntimeClasspath,runtimeClasspath,testR org.apache.tika:tika-core:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-pdf-module:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.tika:tika-parser-xmp-commons:2.9.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-core:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-el:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat.embed:tomcat-embed-websocket:10.1.28=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.apache.tomcat:tomcat-annotations-api:10.1.28=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.30=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat:tomcat-annotations-api:10.1.30=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-anim:1.17=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-awt-util:1.17=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.apache.xmlgraphics:batik-bridge:1.17=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath @@ -154,9 +154,9 @@ org.hamcrest:hamcrest-core:2.2=testCompileClasspath,testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hdrhistogram:HdrHistogram:2.2.2=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=annotationProcessor,productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-envers:6.5.2.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.hibernate.orm:hibernate-jpamodelgen:6.5.2.Final=annotationProcessor +org.hibernate.orm:hibernate-core:6.5.3.Final=annotationProcessor,compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-envers:6.5.3.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.hibernate.orm:hibernate-jpamodelgen:6.5.3.Final=annotationProcessor org.hibernate.validator:hibernate-validator:8.0.1.Final=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt @@ -183,7 +183,7 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.postgresql:postgresql:42.7.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testCompileClasspath,testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -191,30 +191,30 @@ org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeCl org.springdoc:springdoc-openapi-starter-common:2.6.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-api:2.6.0=testCompileClasspath,testRuntimeClasspath org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-actuator:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-aop:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-jdbc:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-json:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-client:3.3.3=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-security:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-tomcat:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-validation:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-web:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-testcontainers:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-jpa:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-actuator:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-aop:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-jdbc:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-client:3.3.4=productionRuntimeClasspath,runtimeClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-security:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-validation:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-testcontainers:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-jpa:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-config:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-core:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-crypto:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -224,19 +224,19 @@ org.springframework.security:spring-security-oauth2-jose:6.3.3=compileClasspath, org.springframework.security:spring-security-oauth2-resource-server:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-test:6.3.3=testCompileClasspath,testRuntimeClasspath org.springframework.security:spring-security-web:6.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aspects:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jdbc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-orm:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-tx:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aspects:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jdbc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-orm:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-tx:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.testcontainers:database-commons:1.19.8=testRuntimeClasspath org.testcontainers:jdbc:1.19.8=testRuntimeClasspath org.testcontainers:postgresql:1.19.8=testRuntimeClasspath diff --git a/backend/travel-medicine/openApi.yaml b/backend/travel-medicine/openApi.yaml index 8a4346a1c0aba4c1e0c759082385f52eece39be4..d6a6a95c8c110de7e43cb056234e951032ee1206 100644 --- a/backend/travel-medicine/openApi.yaml +++ b/backend/travel-medicine/openApi.yaml @@ -3451,8 +3451,12 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 required: - assignee + - taskVersion AssignableService: type: object properties: @@ -4820,7 +4824,7 @@ components: - totalPages GetArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - PROCEDURE_TYPE @@ -5248,7 +5252,7 @@ components: - totalPages GetRelevantArchivableProceduresSortBy: type: string - default: CREATED_AT + default: CLOSED_AT enum: - CLOSED_AT - EXPORTED_AT @@ -7146,6 +7150,11 @@ components: dueAt: type: string format: date-time + taskVersion: + type: integer + format: int64 + required: + - taskVersion ServicePlanEntry: type: object properties: @@ -7321,6 +7330,9 @@ components: $ref: "#/components/schemas/TaskStatus" taskType: $ref: "#/components/schemas/TaskType" + version: + type: integer + format: int64 required: - businessModule - createdAt @@ -7331,6 +7343,7 @@ components: - taskId - taskStatus - taskType + - version TaskMetric: type: object properties: diff --git a/backend/travel-medicine/src/main/java/de/eshg/travelmedicine/testhelper/TravelMedicineTestHelperController.java b/backend/travel-medicine/src/main/java/de/eshg/travelmedicine/testhelper/TravelMedicineTestHelperController.java index 2735f28e0611bd36195e2ad0763be225cf200f1b..260003714c72810da48af7692d60831ced3d7c84 100644 --- a/backend/travel-medicine/src/main/java/de/eshg/travelmedicine/testhelper/TravelMedicineTestHelperController.java +++ b/backend/travel-medicine/src/main/java/de/eshg/travelmedicine/testhelper/TravelMedicineTestHelperController.java @@ -5,7 +5,7 @@ package de.eshg.travelmedicine.testhelper; -import de.eshg.auditlog.AuditLogTestHelperApi; +import de.eshg.auditlog.SharedAuditLogTestHelperApi; import de.eshg.lib.auditlog.AuditLogTestHelperService; import de.eshg.testhelper.ConditionalOnTestHelperEnabled; import de.eshg.testhelper.TestHelperApi; @@ -27,7 +27,7 @@ import org.springframework.web.service.annotation.PostExchange; @RestController @ConditionalOnTestHelperEnabled public class TravelMedicineTestHelperController extends TestHelperController - implements AuditLogTestHelperApi { + implements SharedAuditLogTestHelperApi { public static final String TEST_POPULATION_PATH = "/population"; public static final String TEST_POPULATION_URL = TestHelperApi.BASE_URL + TEST_POPULATION_PATH; diff --git a/backend/util-commons/gradle.lockfile b/backend/util-commons/gradle.lockfile index 8e86ffcabd6e0213f3733560ea088ce9a4ca9c7d..0171e58fa93636a8c9c368daa0deffeb8e1d979b 100644 --- a/backend/util-commons/gradle.lockfile +++ b/backend/util-commons/gradle.lockfile @@ -1,8 +1,8 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -ch.qos.logback:logback-classic:1.5.7=testCompileClasspath,testRuntimeClasspath -ch.qos.logback:logback-core:1.5.7=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.5.8=testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.5.8=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-annotations:2.17.2=testCompileClasspath,testRuntimeClasspath com.fasterxml.jackson.core:jackson-core:2.17.2=testRuntimeClasspath com.fasterxml.jackson.core:jackson-databind:2.17.2=testRuntimeClasspath @@ -16,9 +16,9 @@ com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.9.2=testRuntimeC com.google.code.findbugs:jsr305:3.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.errorprone:error_prone_annotations:2.28.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.guava:failureaccess:1.0.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.guava:guava:33.3.0-jre=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.google.guava:guava:33.3.1-jre=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath,testCompileClasspath +com.google.j2objc:j2objc-annotations:3.0.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.googlecode.java-diff-utils:diffutils:1.3.0=testCompileClasspath,testRuntimeClasspath com.jayway.jsonpath:json-path:2.9.0=testCompileClasspath,testRuntimeClasspath com.sun.istack:istack-commons-runtime:4.1.2=testRuntimeClasspath @@ -28,15 +28,15 @@ com.tngtech.archunit:archunit-junit5-engine:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit-junit5:1.3.0=testRuntimeClasspath com.tngtech.archunit:archunit:1.3.0=testRuntimeClasspath com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath -commons-io:commons-io:2.16.1=testRuntimeClasspath -de.cronn:commons-lang:1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +commons-io:commons-io:2.17.0=testRuntimeClasspath +de.cronn:commons-lang:1.2=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath de.cronn:postgres-snapshot-util:1.1=testRuntimeClasspath de.cronn:test-utils:1.1.1=testCompileClasspath,testRuntimeClasspath de.cronn:validation-file-assertions:0.8.0=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-commons:1.13.3=testCompileClasspath,testRuntimeClasspath -io.micrometer:micrometer-observation:1.13.3=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.13.4=testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.13.4=testCompileClasspath,testRuntimeClasspath io.smallrye:jandex:3.1.2=testRuntimeClasspath -io.swagger.core.v3:swagger-annotations-jakarta:2.2.23=testCompileClasspath,testRuntimeClasspath +io.swagger.core.v3:swagger-annotations-jakarta:2.2.24=testCompileClasspath,testRuntimeClasspath jakarta.activation:jakarta.activation-api:2.1.3=testCompileClasspath,testRuntimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=testCompileClasspath,testRuntimeClasspath jakarta.inject:jakarta.inject-api:2.0.1=testRuntimeClasspath @@ -70,7 +70,7 @@ org.glassfish.jaxb:txw2:4.0.5=testRuntimeClasspath org.hamcrest:hamcrest-core:2.2=testRuntimeClasspath org.hamcrest:hamcrest:2.2=testCompileClasspath,testRuntimeClasspath org.hibernate.common:hibernate-commons-annotations:6.0.6.Final=testRuntimeClasspath -org.hibernate.orm:hibernate-core:6.5.2.Final=testRuntimeClasspath +org.hibernate.orm:hibernate-core:6.5.3.Final=testRuntimeClasspath org.jacoco:org.jacoco.agent:0.8.11=jacocoAgent,jacocoAnt org.jacoco:org.jacoco.ant:0.8.11=jacocoAnt org.jacoco:org.jacoco.core:0.8.11=jacocoAnt @@ -92,29 +92,29 @@ org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.ow2.asm:asm-commons:9.6=jacocoAnt org.ow2.asm:asm-tree:9.6=jacocoAnt org.ow2.asm:asm:9.6=jacocoAnt,testCompileClasspath,testRuntimeClasspath -org.postgresql:postgresql:42.7.3=testRuntimeClasspath +org.postgresql:postgresql:42.7.4=testRuntimeClasspath org.rnorth.duct-tape:duct-tape:1.0.8=testRuntimeClasspath org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath org.slf4j:jul-to-slf4j:2.0.16=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.16=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath org.springframework.boot:spring-boot-dependencies:3.3.3=testRuntimeClasspath -org.springframework.boot:spring-boot-starter-logging:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-starter:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test-autoconfigure:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot-test:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.boot:spring-boot:3.3.3=testCompileClasspath,testRuntimeClasspath -org.springframework.data:spring-data-commons:3.3.3=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-aop:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-beans:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-context:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-core:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-expression:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-jcl:6.1.12=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.springframework:spring-test:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-web:6.1.12=testCompileClasspath,testRuntimeClasspath -org.springframework:spring-webmvc:6.1.12=testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test-autoconfigure:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-test:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.3.4=testCompileClasspath,testRuntimeClasspath +org.springframework.data:spring-data-commons:3.3.4=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.1.13=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-test:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.1.13=testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.1.13=testRuntimeClasspath org.testcontainers:testcontainers:1.19.8=testRuntimeClasspath org.xmlunit:xmlunit-core:2.9.1=testCompileClasspath,testRuntimeClasspath org.yaml:snakeyaml:2.2=testCompileClasspath,testRuntimeClasspath diff --git a/buildSrc/src/main/groovy/eshg.image-push-sign.gradle b/buildSrc/src/main/groovy/eshg.image-push-sign.gradle index 7916173636900372f701d17d123a9edb23afc5cc..9bd992f8755497b7eda0035ddede5be5f19f83c2 100644 --- a/buildSrc/src/main/groovy/eshg.image-push-sign.gradle +++ b/buildSrc/src/main/groovy/eshg.image-push-sign.gradle @@ -65,22 +65,26 @@ tasks.register('pushDockerImage', DockerPushImage) { } tasks.register("signDockerImage", Exec) { - def digest = "" - - commandLine 'cosign', 'sign', digest, - '--annotations', "com.gitlab.ci.pipeline.id=${System.getenv("CI_PIPELINE_ID")}", - '--annotations', "com.gitlab.ci.pipeline.url=${System.getenv("CI_PIPELINE_URL")}", - '--annotations', "com.gitlab.ci.job.id=${System.getenv("CI_JOB_ID")}", - '--annotations', "com.gitlab.ci.job.url=${System.getenv("CI_JOB_URL")}", - '--annotations', "com.gitlab.ci.commit.sha=${System.getenv("CI_COMMIT_SHA")}", - '--annotations', "com.gitlab.ci.commit.ref.name=${System.getenv("CI_COMMIT_REF_NAME")}", - '--annotations', "com.gitlab.ci.project.path=${System.getenv("CI_PROJECT_PATH")}", - '--annotations', "org.opencontainers.image.source=${System.getenv("CI_PROJECT_URL")}", - '--annotations', "org.opencontainers.image.revision=${System.getenv("CI_COMMIT_SHA")}" - doFirst { - assertTagNameIsGiven() - digest = getRepoDigest(getImageNameWithTag()) - } + doFirst { + assertTagNameIsGiven() + } + + def argProv = { + [ + 'sign', getRepoDigest(getImageNameWithTag()), + '--annotations', "com.gitlab.ci.pipeline.id=${System.getenv("CI_PIPELINE_ID")}".toString(), + '--annotations', "com.gitlab.ci.pipeline.url=${System.getenv("CI_PIPELINE_URL")}".toString(), + '--annotations', "com.gitlab.ci.job.id=${System.getenv("CI_JOB_ID")}".toString(), + '--annotations', "com.gitlab.ci.job.url=${System.getenv("CI_JOB_URL")}".toString(), + '--annotations', "com.gitlab.ci.commit.sha=${System.getenv("CI_COMMIT_SHA")}".toString(), + '--annotations', "com.gitlab.ci.commit.ref.name=${System.getenv("CI_COMMIT_REF_NAME")}".toString(), + '--annotations', "com.gitlab.ci.project.path=${System.getenv("CI_PROJECT_PATH")}".toString(), + '--annotations', "org.opencontainers.image.source=${System.getenv("CI_PROJECT_URL")}".toString(), + '--annotations', "org.opencontainers.image.revision=${System.getenv("CI_COMMIT_SHA")}".toString() + ] + } as CommandLineArgumentProvider + executable 'cosign' + argumentProviders.add(argProv) } tasks.register("verifyImageSignature", Exec) { @@ -96,4 +100,4 @@ tasks.register("verifyImageSignature", Exec) { assert project.hasProperty("certificateIdentity"): "certificateIdentity is necessary" assert project.hasProperty("certificateOidcIssuer"): "certificateOidcIssuer is necessary" } -} \ No newline at end of file +} diff --git a/citizen-portal/README.adoc b/citizen-portal/README.adoc index e2a5f558132b3ae524d7fcbb58afc5b5e480f792..744a712261b0979e0c4cfce74bc7765a5b2c655c 100644 --- a/citizen-portal/README.adoc +++ b/citizen-portal/README.adoc @@ -1,4 +1,4 @@ = Citizen Portal :sectnums: -See link:../docs/frontend[here]. \ No newline at end of file +See link:../docs/frontend.adoc[here]. \ No newline at end of file diff --git a/citizen-portal/public/businessBanner1730x320.png b/citizen-portal/public/businessBanner1730x320.png new file mode 100644 index 0000000000000000000000000000000000000000..b5afc4dfd3818172916c46754625eea02783f32c Binary files /dev/null and b/citizen-portal/public/businessBanner1730x320.png differ diff --git a/citizen-portal/public/businessBanner3460x640.png b/citizen-portal/public/businessBanner3460x640.png new file mode 100644 index 0000000000000000000000000000000000000000..1dc31d67f3e6ce54329d93d67f9c6d79ad36f341 Binary files /dev/null and b/citizen-portal/public/businessBanner3460x640.png differ diff --git a/citizen-portal/public/businessBanner720x248.png b/citizen-portal/public/businessBanner720x248.png new file mode 100644 index 0000000000000000000000000000000000000000..129ff38f2aaf839a39a5785684af700a87f059c4 Binary files /dev/null and b/citizen-portal/public/businessBanner720x248.png differ diff --git a/citizen-portal/public/generalBanner1730x320.png b/citizen-portal/public/generalBanner1730x320.png new file mode 100644 index 0000000000000000000000000000000000000000..a5d3e3bc4358618752f523cdee2ed127e38796b9 Binary files /dev/null and b/citizen-portal/public/generalBanner1730x320.png differ diff --git a/citizen-portal/public/generalBanner3460x640.png b/citizen-portal/public/generalBanner3460x640.png new file mode 100644 index 0000000000000000000000000000000000000000..c1b333706e83c9f1bfc79e2b99d6c7253a6f9c0f Binary files /dev/null and b/citizen-portal/public/generalBanner3460x640.png differ diff --git a/citizen-portal/public/generalBanner720x248.png b/citizen-portal/public/generalBanner720x248.png new file mode 100644 index 0000000000000000000000000000000000000000..052b420e5674130a3d7483570a6acfab451a5945 Binary files /dev/null and b/citizen-portal/public/generalBanner720x248.png differ diff --git a/citizen-portal/public/privateBanner1730x320.png b/citizen-portal/public/privateBanner1730x320.png new file mode 100644 index 0000000000000000000000000000000000000000..c6210277258cac21e26359ae088420d192d9965a Binary files /dev/null and b/citizen-portal/public/privateBanner1730x320.png differ diff --git a/citizen-portal/public/privateBanner3460x640.png b/citizen-portal/public/privateBanner3460x640.png new file mode 100644 index 0000000000000000000000000000000000000000..781291ea1179e37a294b2cffbc289968d8223dda Binary files /dev/null and b/citizen-portal/public/privateBanner3460x640.png differ diff --git a/citizen-portal/public/privateBanner720x248.png b/citizen-portal/public/privateBanner720x248.png new file mode 100644 index 0000000000000000000000000000000000000000..8a7db238d2bcd262d32a44492f763035f7260a2d Binary files /dev/null and b/citizen-portal/public/privateBanner720x248.png differ diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/page.tsx index 84a5d8cddbcfd265cac72e19e6ecd2980319f76f..b1c83849bf1ae7d5a3ff6119f2143a8f8cbedab0 100644 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/page.tsx +++ b/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/page.tsx @@ -7,14 +7,14 @@ import { useSuspenseQuery } from "@tanstack/react-query"; -import { PageBanner } from "@/lib/baseModule/components/layout/PageBanner"; import { LandingpageContent } from "@/lib/businessModules/schoolEntry/pages/landingpage/LandingpageContent"; import { LandingpageSidePanel } from "@/lib/businessModules/schoolEntry/pages/landingpage/LandingpageSidePanel"; import { useTranslation } from "@/lib/i18n/client"; import { useDepartmentApi } from "@/lib/shared/api/clients"; import { getDepartmentInfoQuery } from "@/lib/shared/api/queries/department"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; import { TwoColumnGrid } from "@/lib/shared/components/layout/grid"; -import { Page, PageTitle } from "@/lib/shared/components/layout/page"; +import { PageLayout, PageTitle } from "@/lib/shared/components/layout/page"; export default function CitizenSchoolEntryPage() { const { t } = useTranslation(["schoolEntry/overview"]); @@ -24,13 +24,14 @@ export default function CitizenSchoolEntryPage() { ); return ( - <Page> - <PageBanner /> - <PageTitle>{t("pageTitle")}</PageTitle> - <TwoColumnGrid - content={<LandingpageContent departmentInfo={departmentInfo} />} - sidePanel={<LandingpageSidePanel />} - /> - </Page> + <PageLayout banner="private"> + <PageContent> + <PageTitle>{t("pageTitle")}</PageTitle> + <TwoColumnGrid + content={<LandingpageContent departmentInfo={departmentInfo} />} + sidePanel={<LandingpageSidePanel />} + /> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/elternfragebogen/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/elternfragebogen/page.tsx index 862021873b291dd580479ecdf7520a34e32a68af..8a2a9a6802cb3e01e3a7ff3ae3ed3658aa269224 100644 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/elternfragebogen/page.tsx +++ b/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/elternfragebogen/page.tsx @@ -10,7 +10,8 @@ import { useSuspenseQuery } from "@tanstack/react-query"; import { useSchoolEntryCitizenApi } from "@/lib/businessModules/schoolEntry/api/clients"; import { getSelfProcedureAsCitizenQuery } from "@/lib/businessModules/schoolEntry/api/queries/schoolEntryCitizenApi"; import { CitizenAnamnesisForm } from "@/lib/businessModules/schoolEntry/pages/citizenAnamnesis/CitizenAnamnesisForm"; -import { Page } from "@/lib/shared/components/layout/page"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; +import { PageLayout } from "@/lib/shared/components/layout/page"; export default function SchoolEntrySelfAnamnesisPage() { const schoolEntryCitizenApi = useSchoolEntryCitizenApi(); @@ -19,8 +20,10 @@ export default function SchoolEntrySelfAnamnesisPage() { ); return ( - <Page> - <CitizenAnamnesisForm child={procedure.child} /> - </Page> + <PageLayout> + <PageContent> + <CitizenAnamnesisForm child={procedure.child} /> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/page.tsx index 972e71acde82a247dc7784d0b860c618b451ac0b..fb4ae2cec5dd6943dd832d1906f55fa9990ca9de 100644 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/page.tsx +++ b/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/page.tsx @@ -14,8 +14,9 @@ import { AppointmentPageTitle } from "@/lib/businessModules/schoolEntry/pages/ap import { AppointmentSidePanel } from "@/lib/businessModules/schoolEntry/pages/appointment/AppointmentSidePanel"; import { useDepartmentApi } from "@/lib/shared/api/clients"; import { getDepartmentInfoQuery } from "@/lib/shared/api/queries/department"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; import { TwoColumnGrid } from "@/lib/shared/components/layout/grid"; -import { Page } from "@/lib/shared/components/layout/page"; +import { PageLayout } from "@/lib/shared/components/layout/page"; export default function SchoolEntryAppointmentPage() { const departmentApi = useDepartmentApi(); @@ -28,25 +29,27 @@ export default function SchoolEntryAppointmentPage() { }); return ( - <Page> - <AppointmentPageTitle /> - <TwoColumnGrid - content={ - <AppointmentContent - procedure={procedure} - departmentInfo={departmentInfo} - /> - } - sidePanel={ - <AppointmentSidePanel - isClosed={procedure.isClosedProcedure} - appointmentChangesByCitizenLeft={ - procedure.appointmentChangesByCitizenLeft - } - departmentPhoneNumber={departmentInfo.phoneNumber} - /> - } - /> - </Page> + <PageLayout> + <PageContent> + <AppointmentPageTitle /> + <TwoColumnGrid + content={ + <AppointmentContent + procedure={procedure} + departmentInfo={departmentInfo} + /> + } + sidePanel={ + <AppointmentSidePanel + isClosed={procedure.isClosedProcedure} + appointmentChangesByCitizenLeft={ + procedure.appointmentChangesByCitizenLeft + } + departmentPhoneNumber={departmentInfo.phoneNumber} + /> + } + /> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/termin-verschieben/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/termin-verschieben/page.tsx index c771427072347588b9dabe46c1b94f209882517c..bf52097958220339f453b57ea9cd1b750f89f1f5 100644 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/termin-verschieben/page.tsx +++ b/citizen-portal/src/app/[lang]/(privatpersonen)/einschulungsuntersuchung/termin/termin-verschieben/page.tsx @@ -17,7 +17,8 @@ import { import { AppointmentPageTitle } from "@/lib/businessModules/schoolEntry/pages/appointment/AppointmentPageTitle"; import { UpdateAppointmentForm } from "@/lib/businessModules/schoolEntry/pages/appointment/update-appointment/UpdateAppointmentForm"; import { useTranslation } from "@/lib/i18n/client"; -import { Page } from "@/lib/shared/components/layout/page"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; +import { PageLayout } from "@/lib/shared/components/layout/page"; export default function SchoolEntryUpdateAppointmentPage() { const { t } = useTranslation(["schoolEntry/appointment"]); @@ -30,22 +31,24 @@ export default function SchoolEntryUpdateAppointmentPage() { }); return ( - <Page> - <AppointmentPageTitle /> - {procedure.isClosedProcedure ? ( - <Alert - title={t("procedureClosed.title")} - message={t("procedureClosed.message")} - color="warning" - /> - ) : ( - <DisabledFormProvider disabled={procedure.isClosedProcedure}> - <UpdateAppointmentForm - procedure={procedure} - freeAppointments={freeAppointments} + <PageLayout> + <PageContent> + <AppointmentPageTitle /> + {procedure.isClosedProcedure ? ( + <Alert + title={t("procedureClosed.title")} + message={t("procedureClosed.message")} + color="warning" /> - </DisabledFormProvider> - )} - </Page> + ) : ( + <DisabledFormProvider disabled={procedure.isClosedProcedure}> + <UpdateAppointmentForm + procedure={procedure} + freeAppointments={freeAppointments} + /> + </DisabledFormProvider> + )} + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/meine-termine/details/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/meine-termine/details/page.tsx index e4a1eff8452d2269dc52e3591e5f4b8bdaa16d5f..55b2be05099cb6e27d2e7c26cb9015e1f43d7307 100644 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/meine-termine/details/page.tsx +++ b/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/meine-termine/details/page.tsx @@ -13,11 +13,12 @@ import { AppointmentDetailsSidePanel } from "@/lib/businessModules/travelMedicin import { AppointmentPageTitle } from "@/lib/businessModules/travelMedicine/components/viewAppointment/AppointmentPageTitle"; import { useIsMobile } from "@/lib/businessModules/travelMedicine/shared/useIsMobile"; import { useTranslation } from "@/lib/i18n/client"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; import { OneColumnGrid, TwoColumnGrid, } from "@/lib/shared/components/layout/grid"; -import { Page } from "@/lib/shared/components/layout/page"; +import { PageLayout } from "@/lib/shared/components/layout/page"; export default function AppointmentDetailsPage() { const { t } = useTranslation(["travelMedicine/appointmentDetails"]); @@ -31,32 +32,38 @@ export default function AppointmentDetailsPage() { ); return ( - <Page> - <AppointmentPageTitle title={t("header.title")} /> - {isMobile ? ( - <OneColumnGrid - contentTop={ - <AppointmentDetails appointmentDetails={appointmentDetails} /> - } - contentCenter={ - <AppointmentDetailsSidePanel - hasAccomplishedService={appointmentDetails.hasAccomplishedService} - /> - } - contentBottom={null} - /> - ) : ( - <TwoColumnGrid - content={ - <AppointmentDetails appointmentDetails={appointmentDetails} /> - } - sidePanel={ - <AppointmentDetailsSidePanel - hasAccomplishedService={appointmentDetails.hasAccomplishedService} - /> - } - /> - )} - </Page> + <PageLayout> + <PageContent> + <AppointmentPageTitle title={t("header.title")} /> + {isMobile ? ( + <OneColumnGrid + contentTop={ + <AppointmentDetails appointmentDetails={appointmentDetails} /> + } + contentCenter={ + <AppointmentDetailsSidePanel + hasAccomplishedService={ + appointmentDetails.hasAccomplishedService + } + /> + } + contentBottom={null} + /> + ) : ( + <TwoColumnGrid + content={ + <AppointmentDetails appointmentDetails={appointmentDetails} /> + } + sidePanel={ + <AppointmentDetailsSidePanel + hasAccomplishedService={ + appointmentDetails.hasAccomplishedService + } + /> + } + /> + )} + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/meine-termine/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/meine-termine/page.tsx index 04eb957a2f6854a17d820415c308fe0a03cb635e..51b06d6961beff714c9d2fb2d7f2c4951a858221 100644 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/meine-termine/page.tsx +++ b/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/meine-termine/page.tsx @@ -15,8 +15,9 @@ import { TypeSwitchButtons, } from "@/lib/businessModules/travelMedicine/components/viewAppointment/TypeSwitchButtons"; import { useTranslation } from "@/lib/i18n/client"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; import { GridColumnStack } from "@/lib/shared/components/layout/grid"; -import { Page } from "@/lib/shared/components/layout/page"; +import { PageLayout } from "@/lib/shared/components/layout/page"; export default function AppointmentOverviewPage() { const { t } = useTranslation(["travelMedicine/appointmentOverview"]); @@ -28,27 +29,29 @@ export default function AppointmentOverviewPage() { ); return ( - <Page> - <AppointmentPageTitle title={t("header.title")} /> - <TypeSwitchButtons - overviewAppointmentType={overviewAppointmentType} - setOverviewAppointmentType={setOverviewAppointmentType} - /> - <GridColumnStack> - {overviewAppointmentType === OverviewAppointmentTypes.UPCOMING ? ( - <AppointmentOverviewSheet - procedureId={procedureAppointmentData.procedureId} - overviewAppointmentType={OverviewAppointmentTypes.UPCOMING} - appointments={procedureAppointmentData.openAppointments} - /> - ) : ( - <AppointmentOverviewSheet - procedureId={procedureAppointmentData.procedureId} - overviewAppointmentType={OverviewAppointmentTypes.PAST} - appointments={procedureAppointmentData.closedAppointments} - /> - )} - </GridColumnStack> - </Page> + <PageLayout> + <PageContent> + <AppointmentPageTitle title={t("header.title")} /> + <TypeSwitchButtons + overviewAppointmentType={overviewAppointmentType} + setOverviewAppointmentType={setOverviewAppointmentType} + /> + <GridColumnStack> + {overviewAppointmentType === OverviewAppointmentTypes.UPCOMING ? ( + <AppointmentOverviewSheet + procedureId={procedureAppointmentData.procedureId} + overviewAppointmentType={OverviewAppointmentTypes.UPCOMING} + appointments={procedureAppointmentData.openAppointments} + /> + ) : ( + <AppointmentOverviewSheet + procedureId={procedureAppointmentData.procedureId} + overviewAppointmentType={OverviewAppointmentTypes.PAST} + appointments={procedureAppointmentData.closedAppointments} + /> + )} + </GridColumnStack> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/page.tsx index b44ee097d0f1c5ecd2c7a4e296bb0d1cfc3ce12d..6dfe8256eb9bf2630ef883f82b44920db7d0acca 100644 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/page.tsx +++ b/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/page.tsx @@ -7,18 +7,18 @@ import { ApiTravelMedicineFeature } from "@eshg/citizen-portal-api/travelMedicine"; -import { PageBanner } from "@/lib/baseModule/components/layout/PageBanner"; import { useIsNewFeatureEnabled } from "@/lib/businessModules/travelMedicine/api/queries/featureTogglesApi"; import { AppointmentSection } from "@/lib/businessModules/travelMedicine/components/landing/AppointmentSection"; import { LandingpageContent } from "@/lib/businessModules/travelMedicine/components/landing/LandingpageContent"; import { LandingpageSidePanel } from "@/lib/businessModules/travelMedicine/components/landing/LandingpageSidePanel"; import { VaccineOverviewSection } from "@/lib/businessModules/travelMedicine/components/landing/VaccineOverviewSection"; import { useIsMobile } from "@/lib/businessModules/travelMedicine/shared/useIsMobile"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; import { OneColumnGrid, TwoColumnGrid, } from "@/lib/shared/components/layout/grid"; -import { Page, PageTitle } from "@/lib/shared/components/layout/page"; +import { PageLayout, PageTitle } from "@/lib/shared/components/layout/page"; export default function CitizenTravelMedicineEntryPage() { const citizenPortalProcedureEnabled = useIsNewFeatureEnabled( @@ -27,25 +27,26 @@ export default function CitizenTravelMedicineEntryPage() { const isMobile = useIsMobile(); return ( - <Page> - <PageBanner /> - <PageTitle>Reisemedizinische Impfberatung</PageTitle> - {isMobile ? ( - <OneColumnGrid - contentTop={citizenPortalProcedureEnabled && <AppointmentSection />} - contentCenter={<LandingpageContent />} - contentBottom={<VaccineOverviewSection />} - /> - ) : ( - <TwoColumnGrid - content={<LandingpageContent />} - sidePanel={ - <LandingpageSidePanel - citizenPortalProcedureEnabled={citizenPortalProcedureEnabled} - /> - } - /> - )} - </Page> + <PageLayout banner="private"> + <PageContent> + <PageTitle>Reisemedizinische Impfberatung</PageTitle> + {isMobile ? ( + <OneColumnGrid + contentTop={citizenPortalProcedureEnabled && <AppointmentSection />} + contentCenter={<LandingpageContent />} + contentBottom={<VaccineOverviewSection />} + /> + ) : ( + <TwoColumnGrid + content={<LandingpageContent />} + sidePanel={ + <LandingpageSidePanel + citizenPortalProcedureEnabled={citizenPortalProcedureEnabled} + /> + } + /> + )} + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/termin/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/termin/page.tsx index 82a88e433005214a07d44029b17eb54bf1bbe190..73769a0dbf1ac1c9fd000c36ae4e591b9bdec113 100644 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/termin/page.tsx +++ b/citizen-portal/src/app/[lang]/(privatpersonen)/impfberatung/termin/page.tsx @@ -6,12 +6,15 @@ "use client"; import { AppointmentStepper } from "@/lib/businessModules/travelMedicine/components/appointment/AppointmentStepper"; -import { Page } from "@/lib/shared/components/layout/page"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; +import { PageLayout } from "@/lib/shared/components/layout/page"; export default function TravelMedicineAppointmentPage() { return ( - <Page> - <AppointmentStepper /> - </Page> + <PageLayout> + <PageContent> + <AppointmentStepper /> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/masernschutz/hinweise/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/masernschutz/hinweise/page.tsx deleted file mode 100644 index 27efeccdb3da959333e2d9659b381583dc17fcb0..0000000000000000000000000000000000000000 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/masernschutz/hinweise/page.tsx +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export default function OrganizationInspectionPage() { - return ( - <main> - <div> - <h1>Hinweise zum Thema Masernschutz</h1> - </div> - </main> - ); -} diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/masernschutz/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/masernschutz/page.tsx deleted file mode 100644 index 6f87d31616ceb9fb23a4b532f3fde9abbf6e65a4..0000000000000000000000000000000000000000 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/masernschutz/page.tsx +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export default function CitizenMeaslesProtectionPage() { - return ( - <main> - <div> - <h1>Ãœbersicht zum Thema Masernschutz</h1> - </div> - </main> - ); -} diff --git a/citizen-portal/src/app/[lang]/(privatpersonen)/page.tsx b/citizen-portal/src/app/[lang]/(privatpersonen)/page.tsx index 36de79e590f407a3a71430b9dba0450087776204..5d1588be00ed9f92361a371421539d319e715ae5 100644 --- a/citizen-portal/src/app/[lang]/(privatpersonen)/page.tsx +++ b/citizen-portal/src/app/[lang]/(privatpersonen)/page.tsx @@ -5,33 +5,42 @@ "use client"; -import { Box, Typography } from "@mui/joy"; +import { Typography } from "@mui/joy"; +import { useSuspenseQuery } from "@tanstack/react-query"; -import { PageBanner } from "@/lib/baseModule/components/layout/PageBanner"; import { useTranslation } from "@/lib/i18n/client"; +import { useDepartmentApi } from "@/lib/shared/api/clients"; +import { getDepartmentInfoQuery } from "@/lib/shared/api/queries/department"; import { ServiceCardContainer, useMostSearchedCitizenServices, } from "@/lib/shared/components/card/ServiceCardContainer"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; +import { PageLayout } from "@/lib/shared/components/layout/page"; export default function CitizenHomePage() { const { t } = useTranslation(); const mostSearchedCitizenServices = useMostSearchedCitizenServices(); + const departmentApi = useDepartmentApi(); + const { data: departmentInfo } = useSuspenseQuery( + getDepartmentInfoQuery(departmentApi), + ); + return ( - <> - <PageBanner /> - <Box p={4}> - <Typography component="h2" level="h2" mb={2}> - {t("private_person.landing_page.header")} - </Typography> - <Typography mb={4}> - {t("private_person.landing_page.subheader")} - </Typography> - <Typography mb={4}> - {t("private_person.landing_page.contact_us")} - </Typography> + <PageLayout banner="private"> + <PageContent spacing="lg"> + <section> + <Typography component="h2" level="h2" mb={3}> + {t("private_person.landing_page.header")} + </Typography> + <Typography> + {t("private_person.landing_page.subheader", { + name: departmentInfo.name, + })} + </Typography> + </section> <ServiceCardContainer navigationItem={mostSearchedCitizenServices} /> - </Box> - </> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/barrierefreiheit/page.tsx b/citizen-portal/src/app/[lang]/barrierefreiheit/page.tsx index 97bd97aaa41eaf7b808718377be7a77427d1b1ee..37dd04c21ca45557b0c7aaa3dd368ff987d30db8 100644 --- a/citizen-portal/src/app/[lang]/barrierefreiheit/page.tsx +++ b/citizen-portal/src/app/[lang]/barrierefreiheit/page.tsx @@ -5,16 +5,143 @@ "use client"; +import { ExternalLink } from "@eshg/lib-portal/components/navigation/ExternalLink"; import { Typography } from "@mui/joy"; -import { useTranslation } from "@/lib/i18n/client"; import { TitleAndSheetContentLayout } from "@/lib/shared/components/layout/TitleAndSheetContentLayout"; export default function AccessibilityPage() { - const { t } = useTranslation(["accessibility"]); return ( - <TitleAndSheetContentLayout pageTitle={t("pageTitle.accessibility")}> - <Typography>{t("page_under_construction")}</Typography> + <TitleAndSheetContentLayout pageTitle="Erklärung zur Barrierefreiheit"> + <Typography> + Diese Erklärung zur digitalen Barrierefreiheit gilt für die unter + frankfurt.ga-lotse.de veröffentlichte Webseite. + </Typography> + + <Typography> + Als öffentliche Stelle im Sinne der Richtlinie (EU) 2016/2102 sind wir + bemüht, unsere Websites und mobilen Anwendungen im Einklang mit den + Bestimmungen des Hessischen Behinderten-Gleichstellungsgesetzes + (HessBGG) sowie der Hessischen Verordnung über barrierefreie + Informationstechnik (BITV HE 2019) zur Umsetzung der Richtlinie (EU) + 2016/2102 barrierefrei zugänglich zu machen. Frankfurt.ga-lotse.de ist + überwiegend mit den derzeit gültigen Vorschriften zur Barrierefreiheit + (BITV 2.0, 2019/WCAG 2.1) vereinbar. Inhalte und Funktionen, die dem + derzeit noch nicht vollständig entsprechen, sind nachfolgend aufgeführt. + </Typography> + + <Typography level="h4" component="h3"> + Stand der Vereinbarkeit mit den Anforderungen + </Typography> + + <Typography> + Die Anforderungen der Barrierefreiheit ergeben sich aus § 3 Absätze 1 + bis 4 und § 4 der BITV HE 2019, die auf Grundlage von § 14 des HessBGG + erlassen wurde. + </Typography> + + <Typography> + Die Ãœberprüfung der Einhaltung der Anforderungen beruht auf einer am + 16.09.2024 durchgeführten Selbstbewertung. + </Typography> + + <Typography level="h4" component="h3"> + Nicht barrierefreie Inhalte + </Typography> + + <Typography> + Aufgrund der Ãœberprüfung ist die Website mit den zuvor genannten + Anforderungen nur teilweise vereinbar. + </Typography> + <ul> + <li>PDF-Dateien sind nicht vollständig barrierefrei </li> + </ul> + + <Typography> + Die Stadt Frankfurt am Main arbeitet daran, die barrierefreien Angebote + weiter auszubauen. + </Typography> + + <Typography level="h4" component="h3"> + Datum der Erstellung der Erklärung zur Barrierefreiheit + </Typography> + + <Typography> + Diese Erklärung wurde am 16.09.2024 erstellt und zuletzt am 23.09.2024 + überprüft und aktualisiert. + </Typography> + + <Typography level="h4" component="h3"> + Feedback und Anfragen zur digitalen Barrierefreiheit + </Typography> + + <Typography> + Sie möchten uns noch bestehende Barrieren mitteilen oder nicht + barrierefreie Inhalte in einem barrierefreien Format anfordern? Sprechen + Sie unsere verantwortlichen Kontaktpersonen an: + </Typography> + <Typography> + Gesundheitsamt Frankfurt am Main + <br /> + Digitale Zukunft, IT und strategische Planung + <br /> + +49 (0) 800 -4256873 + <br /> + <ExternalLink href="mailto:support@ga-lotse.de"> + support@ga-lotse.de + </ExternalLink> + <br /> + </Typography> + + <Typography level="h4" component="h3"> + Durchsetzungsverfahren + </Typography> + + <Typography> + Wenn auch nach Ihrem Feedback an den oben genannten Kontakt keine + zufriedenstellende Lösung gefunden wurde, können Sie die Durchsetzungs- + und Ãœberwachungsstelle Barrierefreie Informationstechnik einschalten. + Sie haben nach Ablauf einer Frist von sechs Wochen das Recht sich direkt + an die Durchsetzungs- und Ãœberwachungsstelle zu wenden. Unter + Einbeziehung aller Beteiligten versucht die Durchsetzungsstelle, die + Umstände der fehlenden Barrierefreiheit zu ermitteln, damit der Träger + diese beheben kann. + </Typography> + + <Typography> + <strong> + Durchsetzungs- und Ãœberwachungsstelle Barrierefreie + Informationstechnik + </strong> + <br /> + <strong>Hessisches Ministerium für Soziales und Integration</strong> + <br /> + <strong>Sitz: Regierungspräsidium Gießen</strong> + <br /> + Prof. Dr. Erdmuthe Meyer zu Bexten + <br /> + Landesbeauftragte für barrierefreie IT + <br /> + Leiterin der Durchsetzungs- und Ãœberwachungsstelle + <br /> + Landgraf-Philipp-Platz 1-7 + <br /> + 35390 Gießen + <br /> + Telefon: +49 641 303 - 2901 + <br /> + E-Mail:{" "} + <ExternalLink href="mailto:Durchsetzungsstelle-LBIT@rpgi.hessen.de"> + Durchsetzungsstelle-LBIT@rpgi.hessen.de + </ExternalLink> + <br /> + </Typography> + + <Typography> + <ExternalLink href="https://lbit.hessen.de/Durchsetzungs-und-Ueberwachungsstelle/Durchsetzungsverfahren-beantragen/Formular-Durchsetzungsverfahren"> + Durchsetzung beantragen + </ExternalLink> + </Typography> </TitleAndSheetContentLayout> ); } diff --git a/citizen-portal/src/app/[lang]/datenschutz/page.tsx b/citizen-portal/src/app/[lang]/datenschutz/page.tsx index 3d9b303ad0993584338e55ca296864bb13032690..ba5d1099cbc9250d5b850d402e192923159680b2 100644 --- a/citizen-portal/src/app/[lang]/datenschutz/page.tsx +++ b/citizen-portal/src/app/[lang]/datenschutz/page.tsx @@ -7,14 +7,258 @@ import { Typography } from "@mui/joy"; -import { useTranslation } from "@/lib/i18n/client"; import { TitleAndSheetContentLayout } from "@/lib/shared/components/layout/TitleAndSheetContentLayout"; export default function PrivacyPolicyPage() { - const { t } = useTranslation("privacyPolicy"); return ( - <TitleAndSheetContentLayout pageTitle={t("pageTitle.privacy_policy")}> - <Typography>{t("page_under_construction")}</Typography> + <TitleAndSheetContentLayout pageTitle="Datenschutzerklärung"> + <Typography> + Diese Datenschutzerklärung gilt für die Webseite „frankfurt.ga-lotse.de“ + (bzw. „https://frankfurt.ga-lotse.de“ sowie dazu zugehörige Subdomains) + des Gesundheitsamts der Stadt Frankfurt am Main. Dieses + Informationsportal bietet Informationen zu besonderen Ereignissen und + wird ausschließlich zum dem Zwecke genutzt. + </Typography> + <Typography level="h4" component="h3"> + 1. Name und Kontaktdaten des für die Verarbeitung Verantwortlichen sowie + des behördlichen Datenschutzbeauftragten + </Typography> + <Typography> + Diese Datenschutz-Information gilt für die Datenverarbeitung durch: + <br /> + Verantwortlicher: + <br /> + Verantwortlich für die Website „frankfurt.ga-lotse.de“ ist das + Gesundheitsamt Frankfurt am Main: + </Typography> + <Typography> + Gesundheitsamt Frankfurt am Main + <br /> + Breite Gasse 28 + <br /> + 60313 Frankfurt am Main + <br /> + E-Mail: datenschutz.gesundheitsamt@stadt-frankfurt.de + <br /> + </Typography> + <Typography>Behördlicher Datenschutzbeauftragter:</Typography> + <Typography> + Referat Datenschutz und IT-Sicherheit + <br /> + Sandgasse 6, 60311 Frankfurt am Main + </Typography> + <Typography level="h4" component="h3"> + 2. Erhebung und Speicherung personenbezogener Daten sowie Art und Zweck + von deren Verwendung + </Typography> + <Typography level="h4" component="h4"> + 2.1 Beim Besuch der Website + </Typography> + <Typography> + Beim Aufrufen unserer Website „frankfurt.ga-lotse.de“ werden durch den + auf Ihrem Endgerät zum Einsatz kommenden Browser automatisch + Informationen an den Server unserer Website gesendet. Diese + Informationen werden temporär in einem sog. Logfile gespeichert. + Folgende Informationen werden dabei ohne Ihr Zutun erfasst und bis zur + automatisierten Löschung gespeichert: + </Typography> + <ul> + <li>IP-Adresse des anfragenden Rechners</li> + <li>Datum und Uhrzeit des Zugriffs</li> + <li>Name und URL der abgerufenen Datei</li> + <li>Website, von der aus der Zugriff erfolgt (Referrer-URL)</li> + <li> + verwendeter Browser und ggf. das Betriebssystem Ihres Rechners sowie + der Name Ihres Access-Providers + </li> + </ul> + <Typography> + Die genannten Daten werden durch uns zu folgenden Zwecken verarbeitet: + </Typography> + <ul> + <li> + Gewährleistung eines reibungslosen Verbindungsaufbaus der Website + </li> + <li>Gewährleistung einer komfortablen Nutzung unserer Website</li> + <li>Auswertung der Systemsicherheit und -stabilität</li> + <li>Rückverfolgung etwaiger DoS Attacken</li> + <li>sowie zu weiteren administrativen Zwecken</li> + </ul> + <Typography level="h4" component="h4"> + 2.2 Beim Verwenden des QR-Codes + </Typography> + <Typography> + Falls Ihnen für den Zugang zum Online-Portal ein individualisierter + QR-Code gegeben wurde, hat dieser den Zweck, Informationen oder + Nachrichten speziell für Sie zur Verfügung zu stellen, beispielsweise + als betroffener eines gesundheitsrelevanten Ereignisses. Nach Einscannen + des Codes wird man direkt auf die entsprechende Informationsseite + weitergeleitet. Im System wird dabei protokolliert, zu welchem Zeitpunkt + der QR-Code verwendet wurde, jedoch ohne weitere Angaben wie IP-Adresse + oder Namen o.ä. + </Typography> + <Typography> + Die Rechtsgrundlage für die Datenverarbeitung ist Art. 6 Abs. 1 S. 1 + lit. f DS-GVO. Unser berechtigtes Interesse folgt aus oben aufgelisteten + Zwecken zur Datenerhebung. In keinem Fall verwenden wir die erhobenen + Daten zu dem Zweck, Rückschlüsse auf Ihre Person zu ziehen. + </Typography> + <Typography> + Darüber hinaus setzen wir beim Besuch unserer Website Cookies ein. + Nähere Erläuterungen dazu erhalten Sie unter den Ziff. 4 dieser + Datenschutzerklärung. + </Typography> + <Typography level="h4" component="h3"> + 3. Weitergabe von Daten + </Typography> + Es findet keine Weitergabe von Daten an Dritte statt. + <Typography level="h4" component="h3"> + 4. Cookies + </Typography> + <Typography> + Wir setzen auf unserer Seite Cookies ein. Hierbei handelt es sich um + kleine Dateien, die Ihr Browser automatisch erstellt und die auf Ihrem + Endgerät (Laptop, Tablet, Smartphone o.ä.) gespeichert werden, wenn Sie + unsere Seite besuchen. Cookies richten auf Ihrem Endgerät keinen Schaden + an, enthalten keine Viren, Trojaner oder sonstige Schadsoftware. + </Typography> + <Typography> + In dem Cookie werden Informationen abgelegt, die sich jeweils im + Zusammenhang mit dem spezifisch eingesetzten Endgerät ergeben. Dies + bedeutet jedoch nicht, dass wir dadurch unmittelbar Kenntnis von Ihrer + Identität erhalten. + </Typography> + <Typography> + Der Einsatz von Cookies dient einerseits dazu, die Nutzung unseres + Angebots für Sie angenehmer zu gestalten. So setzen wir sogenannte + Session-Cookies ein, um zu erkennen, dass Sie einzelne Seiten unserer + Website bereits besucht haben. Diese werden nach Verlassen unserer Seite + automatisch gelöscht. + </Typography> + <Typography> + Darüber hinaus setzen wir ebenfalls zur Optimierung der + Benutzerfreundlichkeit temporäre Cookies ein, die für einen bestimmten + festgelegten Zeitraum auf Ihrem Endgerät gespeichert werden. Besuchen + Sie unsere Seite erneut, um unsere Dienste in Anspruch zu nehmen, wird + automatischerkannt, dass Sie bereits bei uns waren und welche Eingaben + und Einstellungen sie getätigt haben, um diese nicht noch einmal + eingeben zu müssen. + </Typography> + <Typography> + Die durch Cookies verarbeiteten Daten sind für die genannten Zwecke zur + Wahrung unserer berechtigten Interessen erforderlich. + </Typography> + <Typography> + Die meisten Browser akzeptieren Cookies automatisch. Sie können Ihren + Browser jedoch so konfigurieren, dass keine Cookies auf Ihrem Computer + gespeichert werden oder stets ein Hinweis erscheint, bevor ein neuer + Cookie angelegt wird. Die vollständige Deaktivierung von Cookies kann + jedoch dazu führen, dass Sie nicht alle Funktionen unserer Website + nutzen können. + </Typography> + <Typography level="h4" component="h3"> + 5. Analyse-Tools + </Typography> + <Typography>Es werden keine Analyse-Tools verwendet.</Typography> + <Typography level="h4" component="h3"> + 6. Social Media Plug-ins + </Typography> + <Typography>Es werden keine Social Media Plug-Ins verwendet.</Typography> + <Typography level="h4" component="h3"> + 7. Betroffenenrechte + </Typography> + <Typography>Sie haben das Recht:</Typography> + <ul> + <li> + gemäß Art. 15 DS-GVO Auskunft über Ihre von uns verarbeiteten + personenbezogenen Daten zu verlangen. Insbesondere können Sie Auskunft + über die Verarbeitungszwecke, die Kategorie der personenbezogenen + Daten, die Kategorien von Empfängern, gegenüber denen Ihre Daten + offengelegt wurden oder werden, die geplante Speicherdauer, das + Bestehen eines Rechts auf Berichtigung, Löschung, Einschränkung der + Verarbeitung oder Widerspruch, das Bestehen eines Beschwerderechts, + die Herkunft ihrer Daten, sofern diese nicht bei uns erhoben wurden + sowie über das Bestehen einer automatisierten Entscheidungsfindung + einschließlich Profiling und ggf. aussagekräftigen Informationen zu + deren Einzelheiten verlangen. + </li> + <li> + gemäß Art. 16 DS-GVO unverzüglich die Berichtigung unrichtiger oder + Vervollständigung Ihrer bei uns gespeicherten personenbezogenen Daten + zu verlangen. + </li> + <li> + gemäß Art. 17 DS-GVO die Löschung Ihrer bei uns gespeicherten + personenbezogenen Daten zu verlangen, soweit nicht die Verarbeitung + zur Ausübung des Rechts auf freie Meinungsäußerung und Information, + zur Erfüllung einer rechtlichen Verpflichtung, aus Gründen des + öffentlichen Interesses oder zur Geltendmachung, Ausübung oder + Verteidigung von Rechtsansprüchen erforderlich ist. + </li> + <li> + gemäß Art. 18 DS-GVO die Einschränkung der Verarbeitung Ihrer + personenbezogenen Daten zu verlangen, soweit die Richtigkeit der Daten + von Ihnen bestritten wird, die Verarbeitung unrechtmäßig ist, Sie aber + deren Löschung ablehnen und wir die Daten nicht mehr benötigen, Sie + jedoch diese zur Geltendmachung, Ausübung oder Verteidigung von + Rechtsansprüchen benötigen oder Sie gemäß Art. 21 DS-GVO Widerspruch + gegen die Verarbeitung eingelegt haben. + </li> + <li> + gemäß Art. 20 DS-GVO Ihre personenbezogenen Daten, die Sie uns + bereitgestellt haben, in einem strukturierten, gängigen und + maschinenlesebaren Format zu erhalten oder die Ãœbermittlung an einen + anderen Verantwortlichen zu verlangen. + </li> + <li> + gemäß Art. 7 Abs. 3 DS-GVO Ihre einmal erteilte Einwilligung jederzeit + gegenüber uns zu widerrufen. Dies hat zur Folge, dass wir die + Datenverarbeitung, die auf dieser Einwilligung beruhte, für die + Zukunft nicht mehr fortführen dürfen und + </li> + <li> + gemäß Art. 77 DS-GVO sich bei der zuständigen Aufsichtsbehörde zu + beschweren. Die zuständige Aufsichtsbehörde ist: Der Hessische + Datenschutzbeauftragte, Postfach 3163, 65021 Wiesbaden, Telefon: + 0611/1408 - 0, poststelle@datenschutz-hessen.de. + </li> + </ul> + <Typography level="h4" component="h3"> + 8. Widerspruchsrecht + </Typography> + <Typography> + Sofern Ihre personenbezogenen Daten auf Grundlage von berechtigten + Interessen gemäß Art. 6 Abs. 1 S. 1 lit. f DS-GVO verarbeitet werden, + haben Sie das Recht, gemäß Art. 21 DS-GVO Widerspruch gegen die + Verarbeitung Ihrer personenbezogenen Daten einzulegen, soweit dafür + Gründe vorliegen, die sich aus Ihrer besonderen Situation ergeben. + Möchten Sie von Ihrem Widerrufs- oder Widerspruchsrecht Gebrauch machen, + genügt eine E-Mail an datenschutz.gesundheitsamt@stadt-frankfurt.de. + </Typography> + <Typography level="h4" component="h3"> + 9. Datensicherheit + </Typography> + <Typography> + Wir bedienen uns geeigneter technischer und organisatorischer + Sicherheitsmaßnahmen, um Ihre Daten gegen zufällige oder vorsätzliche + Manipulationen, teilweisen oder vollständigen Verlust, Zerstörung oder + gegen den unbefugten Zugriff Dritter zu schützen. Unsere + Sicherheitsmaßnahmen werden nach dem jeweiligen Stand der Technik gemäß + Art. 32 DS-GVO fortlaufend angepasst. + </Typography> + <Typography level="h4" component="h3"> + 10. Auftragsverarbeitung + </Typography> + <Typography> + Es findet keine Auftragsverarbeitung der erhobenen Daten statt. + </Typography> + <Typography level="h4" component="h3"> + 11. Aktualität und Änderung dieser Datenschutzerklärung + </Typography> + <Typography> + Diese Datenschutzerklärung ist aktuell gültig und hat den Stand + September 2024. + </Typography> </TitleAndSheetContentLayout> ); } diff --git a/citizen-portal/src/app/[lang]/error.tsx b/citizen-portal/src/app/[lang]/error.tsx index d4334a6d1638d22fefa91e29cf6d94ffa668cdba..c6c8ce9bc5dce76b18d1da338c2de2cc75507743 100644 --- a/citizen-portal/src/app/[lang]/error.tsx +++ b/citizen-portal/src/app/[lang]/error.tsx @@ -5,6 +5,20 @@ "use client"; -import { NextErrorBoundary } from "@eshg/lib-portal/components/boundaries/NextErrorBoundary"; +import { + NextErrorBoundary, + NextErrorBoundaryProps, +} from "@eshg/lib-portal/components/boundaries/NextErrorBoundary"; -export default NextErrorBoundary; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; +import { PageLayout } from "@/lib/shared/components/layout/page"; + +export default function RootError(props: NextErrorBoundaryProps) { + return ( + <PageLayout> + <PageContent> + <NextErrorBoundary {...props} /> + </PageContent> + </PageLayout> + ); +} diff --git a/citizen-portal/src/app/[lang]/impressum/page.tsx b/citizen-portal/src/app/[lang]/impressum/page.tsx index 205b595d78a2228dae27883dc1c6fb2cd6f07030..83dfdc5f93602fd691962236048ab741dcb3387a 100644 --- a/citizen-portal/src/app/[lang]/impressum/page.tsx +++ b/citizen-portal/src/app/[lang]/impressum/page.tsx @@ -5,16 +5,125 @@ "use client"; +import { ExternalLink } from "@eshg/lib-portal/components/navigation/ExternalLink"; +import { InternalLink } from "@eshg/lib-portal/components/navigation/InternalLink"; import { Typography } from "@mui/joy"; -import { useTranslation } from "@/lib/i18n/client"; +import { useRoutes } from "@/lib/baseModule/shared/routes"; import { TitleAndSheetContentLayout } from "@/lib/shared/components/layout/TitleAndSheetContentLayout"; export default function ImprintPage() { - const { t } = useTranslation(["imprint"]); + const routes = useRoutes(); + return ( - <TitleAndSheetContentLayout pageTitle={t("pageTitle.imprint")}> - <Typography>{t("page_under_construction")}</Typography> + <TitleAndSheetContentLayout pageTitle="Impressum"> + <Typography level="h4" component="h3"> + Gesamtverantwortung: + </Typography> + <Typography> + Stadt Frankfurt am Main + <br /> + DER MAGISTRAT + <br /> + Römerberg 23 + <br /> + 60311 Frankfurt am Main + <br /> + Website: www.frankfurt.de + <br /> + <br /> + USt-ID: DE 114 110 388 + </Typography> + + <Typography level="h4" component="h3"> + Verantwortung für das GA-Lotse Online-Portal: + </Typography> + <Typography> + Stadt Frankfurt am Main + <br /> + DER MAGISTRAT + <br /> + Gesundheitsamt Frankfurt am Main + <br /> + Abteilung Digitale Zukunft, IT und strategische Planung + <br /> + Breite Gasse 28 + <br /> + 60313 Frankfurt am Main + </Typography> + + <Typography> + GA-Lotse ist ein Kooperationsprojekt des Hessischen Ministeriums für + Familie, Senioren, Sport, Gesundheit und Pflege mit dem Gesundheitsamt + Frankfurt unter der EU-Förderung NextGenerationEU. + </Typography> + <Typography level="h4" component="h3"> + Telefonische Auskünfte: + </Typography> + <Typography> + Informationen erhalten Sie über die Rufnummer: +49 (0) 800 -4256873 + </Typography> + + <Typography level="h4" component="h3"> + Kontakt bei Presseanfragen: + </Typography> + <Typography> + <ExternalLink + href={`mailto:gesundheitsamt.einheitliche-software@stadt-frankfurt.de`} + > + gesundheitsamt.einheitliche-software@stadt-frankfurt.de + </ExternalLink> + </Typography> + + <Typography level="h4" component="h3"> + Kontakt bei Fragen zum GA-Lotse Online-Portal: + </Typography> + <Typography> + eMail: gesundheitsamt.einheitliche-software@stadt-frankfurt.de + <br /> + Die Abteilung Digitale Zukunft, IT und strategische Planung des + Gesundheitsamtes der Stadt Frankfurt am Main zeichnet für ihre Inhalte + auf www.ga-lotse.de redaktionell verantwortlich. + </Typography> + + <Typography level="h4" component="h3"> + Verantwortung: + </Typography> + <Typography> + Stefanie Kaulich, Abteilungsleitung Digitale Zukunft, IT und + strategische Planung. <br /> + Bei Fragen oder Anregungen zu konkreten Inhalten und Seiten können Sie + sich gerne an Frau Kaulich oder die unter „Kontakt“ benannte eMail + wenden. + </Typography> + + <Typography level="h4" component="h3"> + Technische Realisierung: + </Typography> + <Typography> + Gesundheitsamt der Stadt Frankfurt am Main + <br /> + Abteilung Digitale Zukunft, IT und strategische Planung + <br /> + Breite Gasse 28 + <br /> + 60313 Frankfurt am Main + </Typography> + + <Typography level="h4" component="h3"> + Bei Fragen oder Anmerkungen: + </Typography> + <Typography> + gesundheitsamt.einheitliche-software@stadt-frankfurt.de + </Typography> + + <Typography level="h4" component="h3"> + Hinweise zum Datenschutz: + </Typography> + <Typography> + Informationen zum Datenschutz finden Sie{" "} + <InternalLink href={routes.privacyPolicy}>hier</InternalLink>. + </Typography> </TitleAndSheetContentLayout> ); } diff --git a/citizen-portal/src/app/[lang]/loading.tsx b/citizen-portal/src/app/[lang]/loading.tsx index 8859bac9f430d34aa605daf97b68ac4ad9374002..55a1325afff56dbdb962c4b67b8d584f60929055 100644 --- a/citizen-portal/src/app/[lang]/loading.tsx +++ b/citizen-portal/src/app/[lang]/loading.tsx @@ -5,6 +5,15 @@ import { LoadingIndicator } from "@eshg/lib-portal/components/LoadingIndicator"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; +import { PageLayout } from "@/lib/shared/components/layout/page"; + export default function Loading() { - return <LoadingIndicator text="Seite wird geladen…" fullHeight />; + return ( + <PageLayout> + <PageContent fullHeight> + <LoadingIndicator text="Seite wird geladen…" fullHeight flexGrow={1} /> + </PageContent> + </PageLayout> + ); } diff --git a/citizen-portal/src/app/[lang]/nutzungshinweise/page.tsx b/citizen-portal/src/app/[lang]/nutzungshinweise/page.tsx index c8757e244dda8794e0f05dac991f803439cddac7..a717ff30938a7d79e7844167a7587115cba6488f 100644 --- a/citizen-portal/src/app/[lang]/nutzungshinweise/page.tsx +++ b/citizen-portal/src/app/[lang]/nutzungshinweise/page.tsx @@ -5,16 +5,62 @@ "use client"; +import { ExternalLink } from "@eshg/lib-portal/components/navigation/ExternalLink"; import { Typography } from "@mui/joy"; -import { useTranslation } from "@/lib/i18n/client"; import { TitleAndSheetContentLayout } from "@/lib/shared/components/layout/TitleAndSheetContentLayout"; export default function TermsOfUsePage() { - const { t } = useTranslation("termsOfUse"); return ( - <TitleAndSheetContentLayout pageTitle={t("pageTitle.terms_of_use")}> - <Typography>{t("page_under_construction")}</Typography> + <TitleAndSheetContentLayout pageTitle="Nutzungshinweise für die sichere Benutzung des Online-Portals"> + <Typography> + Wir empfehlen die Beachtung der folgenden Hinweise zur sicheren + Benutzung des Online-Portals. + </Typography> + + <ol> + <li> + <strong>Aktuellen Browser und Betriebssystem verwenden</strong> + <br /> + Um eine optimale Nutzung und Sicherheit zu gewährleisten, empfehlen + wir die Nutzung eines möglichst aktuellen Browsers und + Betriebssystems. Das Online-Portal wurde mit den gängigsten Browsern + (Google Chrome, Mozilla Firefox, Microsoft Edge, Apple Safari) auf + unterschiedlichen Plattformen (Desktop, Mobile, Smartphone) getestet. + Regelmäßige Updates schützen vor Sicherheitslücken und stellen sicher, + dass die Anwendung korrekt funktioniert. + </li> + <li> + <strong>QR-Codes und Zugangscodes sicher verwahren</strong> + <br /> + Bewahren Sie QR-Codes sowie Zugangscodes sicher auf und teilen Sie + diese nicht mit unbefugten Personen. Diese Codes sind der Schlüssel zu + Ihrem Konto mit sensiblen Informationen und sollten daher nur von + Ihnen selbst genutzt werden. + </li> + <li> + <strong>Gerät bei Nichtbenutzung sperren</strong> + <br /> + Stellen Sie sicher, dass Ihr Computer, Smartphone oder Tablet bei + Nichtbenutzung immer gesperrt ist. Dies schützt Ihre Daten vor + unbefugtem Zugriff, falls Sie Ihr Gerät unbeaufsichtigt lassen. + </li> + <li> + <strong>Browser nach der Nutzung der Anwendung schließen</strong> + <br /> + Um Ihre Privatsphäre zu schützen, schließen Sie nach der Nutzung der + Anwendung Ihren Browser. So verhindern Sie, dass sensible Daten im + Zwischenspeichers Ihres Geräts gespeichert bleiben. + </li> + </ol> + + <Typography> + Weitere Hinweise zur sicheren Nutzung finden Sie auf den{" "} + <ExternalLink href="https://www.bsi.bund.de/DE/Themen/Verbraucherinnen-und-Verbraucher/Informationen-und-Empfehlungen/Cyber-Sicherheitsempfehlungen/cyber-sicherheitsempfehlungen_node.html"> + Webseiten + </ExternalLink>{" "} + des Bundesamts für Sicherheit in der Informationstechnik (BSI). + </Typography> </TitleAndSheetContentLayout> ); } diff --git a/citizen-portal/src/app/[lang]/playground/page.tsx b/citizen-portal/src/app/[lang]/playground/page.tsx index 529557e51f192a795c36bb8eccabb0575d0d00a7..600f3015547f541245c8e678d3aa0061ef8c7102 100644 --- a/citizen-portal/src/app/[lang]/playground/page.tsx +++ b/citizen-portal/src/app/[lang]/playground/page.tsx @@ -8,17 +8,20 @@ import { InternalLink } from "@eshg/lib-portal/components/navigation/InternalLink"; import { List, ListItem } from "@mui/joy"; -import { Page, PageTitle } from "@/lib/shared/components/layout/page"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; +import { PageLayout, PageTitle } from "@/lib/shared/components/layout/page"; export default function CitizenSchoolEntryPage() { return ( - <Page> - <PageTitle>Playground</PageTitle> - <List marker="disc"> - <ListItem> - <InternalLink href="/playground/snackbar">Snackbar</InternalLink> - </ListItem> - </List> - </Page> + <PageLayout> + <PageContent> + <PageTitle>Playground</PageTitle> + <List marker="disc"> + <ListItem> + <InternalLink href="/playground/snackbar">Snackbar</InternalLink> + </ListItem> + </List> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/playground/snackbar/page.tsx b/citizen-portal/src/app/[lang]/playground/snackbar/page.tsx index 449a0c63e17ed7ebf58f305a0f172bce50298331..a3a452aca770c639160cb38817e46ca5ee448668 100644 --- a/citizen-portal/src/app/[lang]/playground/snackbar/page.tsx +++ b/citizen-portal/src/app/[lang]/playground/snackbar/page.tsx @@ -18,8 +18,9 @@ import { } from "@mui/joy"; import { useState } from "react"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; import { ContentSheet } from "@/lib/shared/components/layout/contentSheet"; -import { Page, PageTitle } from "@/lib/shared/components/layout/page"; +import { PageLayout, PageTitle } from "@/lib/shared/components/layout/page"; const DEFAULT_TYPE = "confirmation"; const TYPES = ["confirmation", "error", "notification"] as const; @@ -41,43 +42,45 @@ export default function SnackbarPlaygroundPage() { } return ( - <Page> - <PageTitle>Snackbar</PageTitle> - <ContentSheet> - <FormControl> - <FormLabel>Type</FormLabel> - <Select - value={type} - onChange={(_, value) => setType(value ?? DEFAULT_TYPE)} - > - {TYPES.map((type) => ( - <Option key={type} value={type}> - {type} - </Option> - ))} - </Select> - </FormControl> - <FormControl> - <FormLabel>Text</FormLabel> - <Input - value={text} - onChange={(event) => setText(event.target.value)} + <PageLayout> + <PageContent> + <PageTitle>Snackbar</PageTitle> + <ContentSheet> + <FormControl> + <FormLabel>Type</FormLabel> + <Select + value={type} + onChange={(_, value) => setType(value ?? DEFAULT_TYPE)} + > + {TYPES.map((type) => ( + <Option key={type} value={type}> + {type} + </Option> + ))} + </Select> + </FormControl> + <FormControl> + <FormLabel>Text</FormLabel> + <Input + value={text} + onChange={(event) => setText(event.target.value)} + /> + </FormControl> + <Checkbox + label="Manual close" + checked={manualClose} + onChange={(event) => setManualClose(event.target.checked)} /> - </FormControl> - <Checkbox - label="Manual close" - checked={manualClose} - onChange={(event) => setManualClose(event.target.checked)} - /> - <FormControl> - <FormLabel>Action</FormLabel> - <Input - value={action} - onChange={(event) => setAction(event.target.value)} - /> - </FormControl> - <Button onClick={openSnackbar}>Snackbar öffnen</Button> - </ContentSheet> - </Page> + <FormControl> + <FormLabel>Action</FormLabel> + <Input + value={action} + onChange={(event) => setAction(event.target.value)} + /> + </FormControl> + <Button onClick={openSnackbar}>Snackbar öffnen</Button> + </ContentSheet> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/template.tsx b/citizen-portal/src/app/[lang]/template.tsx index 04ce83e943496a8d7f14ea4dceb1710c395ca12b..36fdf6f5529b1408c7e547b636de0564e774e7c3 100644 --- a/citizen-portal/src/app/[lang]/template.tsx +++ b/citizen-portal/src/app/[lang]/template.tsx @@ -4,16 +4,5 @@ */ import { QueryBoundary } from "@eshg/lib-portal/components/boundaries/QueryBoundary"; -import { ScopedAlert } from "@eshg/lib-portal/errorHandling/AlertContext"; -import { RequiresChildren } from "@eshg/lib-portal/types/react"; -import { PAGE_ALERT_STYLE } from "@/lib/styles"; - -export default function RootTemplate(props: RequiresChildren) { - return ( - <QueryBoundary> - <ScopedAlert sx={PAGE_ALERT_STYLE} /> - {props.children} - </QueryBoundary> - ); -} +export default QueryBoundary; diff --git a/citizen-portal/src/app/[lang]/unternehmen/masernschutz/hinweise/page.tsx b/citizen-portal/src/app/[lang]/unternehmen/masernschutz/hinweise/page.tsx deleted file mode 100644 index 473eb70acc7691f2c2e0083bdab38cbad3132495..0000000000000000000000000000000000000000 --- a/citizen-portal/src/app/[lang]/unternehmen/masernschutz/hinweise/page.tsx +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export default function OrganizationInspectionPage() { - return ( - <main> - <div> - <h1>Hinweise zum Thema Masernschutz für Unternehmen</h1> - </div> - </main> - ); -} diff --git a/citizen-portal/src/app/[lang]/unternehmen/masernschutz/meldeformular/page.tsx b/citizen-portal/src/app/[lang]/unternehmen/masernschutz/meldeformular/page.tsx index 9cea237829ed8e173e2538f623e90bb9d648590e..95c007a6014974f8143f83f71e12ac2e1ef1a1c0 100644 --- a/citizen-portal/src/app/[lang]/unternehmen/masernschutz/meldeformular/page.tsx +++ b/citizen-portal/src/app/[lang]/unternehmen/masernschutz/meldeformular/page.tsx @@ -7,7 +7,6 @@ import { ApiReportCaseRequest } from "@eshg/citizen-portal-api/measlesProtection"; import { useHandledMutation } from "@eshg/lib-portal/api/useHandledMutation"; -import { Box, Typography } from "@mui/joy"; import { useOrganisationPortalApi } from "@/lib/businessModules/measlesProtection/api/clients"; import { ReportCaseForm } from "@/lib/businessModules/measlesProtection/components/reportCase/ReportCaseForm"; @@ -19,6 +18,8 @@ import { import { setReportCaseForm } from "@/lib/businessModules/measlesProtection/helpers/reportCaseForm.storage"; import { mapFacilityToApiAddFacilityFileStateRequest } from "@/lib/businessModules/measlesProtection/shared/facility/helpers"; import { useTranslation } from "@/lib/i18n/client"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; +import { PageLayout, PageTitle } from "@/lib/shared/components/layout/page"; function mapMeaslesCaseReport(report: ReportMeaslesCase): ApiReportCaseRequest { const apiReportCaseRequest: ApiReportCaseRequest = { @@ -50,17 +51,11 @@ export default function CitizenMeaslesProtectionReportCasePage() { } return ( - <div> - <Box sx={{ borderRadius: "xl", backgroundColor: "white", p: 2, my: 2 }}> - <Typography - component="h2" - level="h2" - sx={{ fontSize: { xxs: "1.25rem", sm: "2.25rem" } }} - > - {t("reportMeaslesCaseForm.pageTitle")} - </Typography> - </Box> - <ReportCaseForm onSubmit={handleSubmit} /> - </div> + <PageLayout> + <PageContent> + <PageTitle>{t("reportMeaslesCaseForm.pageTitle")}</PageTitle> + <ReportCaseForm onSubmit={handleSubmit} /> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/unternehmen/masernschutz/page.tsx b/citizen-portal/src/app/[lang]/unternehmen/masernschutz/page.tsx index 9bef3d04fbe9b006c9dfe00e5ba694e3acec3976..9792c4441a8c04398bdd787de321f744521f4237 100644 --- a/citizen-portal/src/app/[lang]/unternehmen/masernschutz/page.tsx +++ b/citizen-portal/src/app/[lang]/unternehmen/masernschutz/page.tsx @@ -5,23 +5,24 @@ "use client"; -import { PageBanner } from "@/lib/baseModule/components/layout/PageBanner"; import { LandingpageContent } from "@/lib/businessModules/measlesProtection/pages/landingPage/LandingpageContent"; import { LandingpageSidePanel } from "@/lib/businessModules/measlesProtection/pages/landingPage/LandingpageSidePanel"; import { useTranslation } from "@/lib/i18n/client"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; import { TwoColumnGrid } from "@/lib/shared/components/layout/grid"; -import { Page, PageTitle } from "@/lib/shared/components/layout/page"; +import { PageLayout, PageTitle } from "@/lib/shared/components/layout/page"; export default function CitizenMeaslesProtectionPage() { const { t } = useTranslation("measlesProtection/overview"); return ( - <Page> - <PageBanner /> - <PageTitle>{t("page_title")}</PageTitle> - <TwoColumnGrid - content={<LandingpageContent />} - sidePanel={<LandingpageSidePanel />} - /> - </Page> + <PageLayout banner="business"> + <PageContent> + <PageTitle>{t("page_title")}</PageTitle> + <TwoColumnGrid + content={<LandingpageContent />} + sidePanel={<LandingpageSidePanel />} + /> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/app/[lang]/unternehmen/page.tsx b/citizen-portal/src/app/[lang]/unternehmen/page.tsx index 75dba40072101b164d214b274177c418b877f594..47daddcf83b90540a26d1a585c1fa4150eaa3130 100644 --- a/citizen-portal/src/app/[lang]/unternehmen/page.tsx +++ b/citizen-portal/src/app/[lang]/unternehmen/page.tsx @@ -5,28 +5,36 @@ "use client"; -import { Box, Typography } from "@mui/joy"; +import { Typography } from "@mui/joy"; +import { useSuspenseQuery } from "@tanstack/react-query"; -import { PageBanner } from "@/lib/baseModule/components/layout/PageBanner"; import { useTranslation } from "@/lib/i18n/client"; +import { useDepartmentApi } from "@/lib/shared/api/clients"; +import { getDepartmentInfoQuery } from "@/lib/shared/api/queries/department"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; +import { PageLayout } from "@/lib/shared/components/layout/page"; export default function OrganizationHomePage() { const { t } = useTranslation(); + const departmentApi = useDepartmentApi(); + const { data: departmentInfo } = useSuspenseQuery( + getDepartmentInfoQuery(departmentApi), + ); return ( - <> - <PageBanner /> - <Box p={4}> - <Typography component="h2" level="h2" mb={2}> - {t("organization.landing_page.header")} - </Typography> - <Typography mb={4}> - {t("organization.landing_page.subheader")} - </Typography> - <Typography mb={4}> - {t("organization.landing_page.contact_us")} - </Typography> - </Box> - </> + <PageLayout banner="business"> + <PageContent spacing="lg"> + <section> + <Typography component="h2" level="h2" mb={3}> + {t("organization.landing_page.header")} + </Typography> + <Typography> + {t("organization.landing_page.subheader", { + name: departmentInfo.name, + })} + </Typography> + </section> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/lib/baseModule/components/ContactInformation.tsx b/citizen-portal/src/lib/baseModule/components/ContactInformation.tsx index 9d97bb76ff2487f295ada212bb5133830549a556..f070da4b3a1180acc0b27ab66e9f8140d3b57e06 100644 --- a/citizen-portal/src/lib/baseModule/components/ContactInformation.tsx +++ b/citizen-portal/src/lib/baseModule/components/ContactInformation.tsx @@ -109,7 +109,7 @@ function InternetSection(props: DepartmentInfoProps) { justifyContent: "space-between", wordBreak: "break-all", }} - href={`${homepage}`} + href={`https://${homepage}`} endDecorator={<ArrowRightAltOutlined />} > {t("health_department")} diff --git a/citizen-portal/src/lib/baseModule/components/layout/MainLayout.tsx b/citizen-portal/src/lib/baseModule/components/layout/MainLayout.tsx index ca77f1173cc7200366ccd8b14e25d907d8f748a7..1fc6dcebbc4297ff40e4e9b7e4817de87648c07e 100644 --- a/citizen-portal/src/lib/baseModule/components/layout/MainLayout.tsx +++ b/citizen-portal/src/lib/baseModule/components/layout/MainLayout.tsx @@ -5,23 +5,27 @@ "use client"; -import { Box } from "@mui/joy"; -import { ReactNode } from "react"; +import { RequiresChildren } from "@eshg/lib-portal/types/react"; +import { styled } from "@mui/joy"; -import { Content } from "@/lib/baseModule/components/layout/Content"; import { Footer } from "@/lib/baseModule/components/layout/Footer"; +import { NavigationMenu } from "@/lib/baseModule/components/layout/navigationMenu/NavigationMenu"; import { useGetDepartmentInfo } from "@/lib/shared/api/queries/department"; -import { NavigationMenu } from "./navigationMenu/NavigationMenu"; +const FullWidthContainer = styled("div")({ + flex: 1, + display: "flex", + flexDirection: "column", + width: "100%", + alignItems: "center", +}); -export function MainLayout({ children }: { children: ReactNode }) { +export function MainLayout({ children }: RequiresChildren) { const { data: department } = useGetDepartmentInfo(); return ( <> <NavigationMenu /> - <Content> - <Box component="main">{children}</Box> - </Content> + <FullWidthContainer>{children}</FullWidthContainer> <Footer department={department} /> </> ); diff --git a/citizen-portal/src/lib/baseModule/components/layout/sizes.ts b/citizen-portal/src/lib/baseModule/components/layout/sizes.ts index c158ba8fb8df3a0349e5eea55ebd0f2be5ec1ce9..2ffea415320fc7c44224b9839d103c41ffae2c4e 100644 --- a/citizen-portal/src/lib/baseModule/components/layout/sizes.ts +++ b/citizen-portal/src/lib/baseModule/components/layout/sizes.ts @@ -16,7 +16,7 @@ export const bannerHeightDesktop = "20rem"; // 320px export const maxContentWidthDesktop = "1232px"; export const contentMarginDesktop: ContentMargin = { - topBottom: 5, + topBottom: 3, leftRight: 3.5, }; export const contentMarginMobile: ContentMargin = { diff --git a/citizen-portal/src/lib/baseModule/locales/de/accessibility.json b/citizen-portal/src/lib/baseModule/locales/de/accessibility.json deleted file mode 100644 index 79bcc494fd7fc5166c2287dcba1f07f36e451806..0000000000000000000000000000000000000000 --- a/citizen-portal/src/lib/baseModule/locales/de/accessibility.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pageTitle": { - "accessibility": "Barrierefreiheit" - }, - "page_under_construction": "Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie vom Gesundheitsamt freigegeben sind." -} diff --git a/citizen-portal/src/lib/baseModule/locales/de/imprint.json b/citizen-portal/src/lib/baseModule/locales/de/imprint.json deleted file mode 100644 index 7df2d11d9ec93c1df88794bfa872af014a1d2db8..0000000000000000000000000000000000000000 --- a/citizen-portal/src/lib/baseModule/locales/de/imprint.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pageTitle": { - "imprint": "Impressum" - }, - "page_under_construction": "Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie vom Gesundheitsamt freigegeben sind." -} diff --git a/citizen-portal/src/lib/baseModule/locales/de/privacyPolicy.json b/citizen-portal/src/lib/baseModule/locales/de/privacyPolicy.json deleted file mode 100644 index 085bc1a51e0a52ee5daa60d010216f1add621f69..0000000000000000000000000000000000000000 --- a/citizen-portal/src/lib/baseModule/locales/de/privacyPolicy.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pageTitle": { - "privacy_policy": "Datenschutzerklärung" - }, - "page_under_construction": "Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie vom Gesundheitsamt freigegeben sind." -} diff --git a/citizen-portal/src/lib/baseModule/locales/de/termsOfUse.json b/citizen-portal/src/lib/baseModule/locales/de/termsOfUse.json deleted file mode 100644 index 11adfc0f661aab8f0b874ef7a79747bd8ea06a65..0000000000000000000000000000000000000000 --- a/citizen-portal/src/lib/baseModule/locales/de/termsOfUse.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pageTitle": { - "terms_of_use": "Nutzungshinweise" - }, - "page_under_construction": "Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie vom Gesundheitsamt freigegeben sind." -} diff --git a/citizen-portal/src/lib/baseModule/locales/de/translation.json b/citizen-portal/src/lib/baseModule/locales/de/translation.json index 7fedf54b6589c713ba15701c6bc1df2daca7a03d..d19eaf06845537e46a63419d835ee53b38a78eff 100644 --- a/citizen-portal/src/lib/baseModule/locales/de/translation.json +++ b/citizen-portal/src/lib/baseModule/locales/de/translation.json @@ -1,22 +1,19 @@ { "organization": { "landing_page": { - "header": "Willkommen im Gesundheitsamt. ðŸ¢", - "subheader": "Wir freuen uns, Sie hier begrüßen zu dürfen. Unser Team steht Ihnen zur Verfügung, um Ihnen bei allen Fragen und Anliegen im Bereich der öffentlichen Gesundheit behilflich zu sein. Ihre Gesundheit liegt uns am Herzen, und wir setzen uns mit Fachkompetenz und Engagement für Ihr Wohlbefinden ein.", - "contact_us": "Bitte zögern Sie nicht, sich an uns zu wenden, wenn Sie Unterstützung benötigen oder Informationen zu gesundheitsbezogenen Themen suchen. Wir helfen und beraten Sie gerne." + "header": "Willkommen im Gesundheitsamt.", + "subheader": "Das {{name}} bietet umfangreiche Leistungen zum Schutz und zur Wiederherstellung der Gesundheit an." } }, "private_person": { "landing_page": { "header": "Willkommen im Gesundheitsamt.", - "subheader": "Wir freuen uns, Sie hier begrüßen zu dürfen. Unser Team steht Ihnen zur Verfügung, um Ihnen bei allen Fragen und Anliegen im Bereich der öffentlichen Gesundheit behilflich zu sein. Ihre Gesundheit liegt uns am Herzen, und wir setzen uns mit Fachkompetenz und Engagement für Ihr Wohlbefinden ein.", - "contact_us": "Bitte zögern Sie nicht, sich an uns zu wenden, wenn Sie Unterstützung benötigen oder Informationen zu gesundheitsbezogenen Themen suchen. Wir helfen und beraten Sie gerne." + "subheader": "Das {{name}} bietet umfangreiche Leistungen zum Schutz und zur Wiederherstellung der Gesundheit an." } }, "site_title": "Online-Portal", "site_description": "Von Bürgern für Bürger", "health_department_title": "Gesundheitsamt", - "health_officers_link": "Amtsärztin / Amtsarzt", "most_searched_services_title": "Meistgesuchte Services", "common": { "address": "Adresse", diff --git a/citizen-portal/src/lib/baseModule/locales/en/accessibility.json b/citizen-portal/src/lib/baseModule/locales/en/accessibility.json deleted file mode 100644 index 112ebbd0ba0ce6eec42113c70efd0e7dd006f5c0..0000000000000000000000000000000000000000 --- a/citizen-portal/src/lib/baseModule/locales/en/accessibility.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pageTitle": { - "accessibility": "Accessibility" - }, - "page_under_construction": "This page is currently under construction. The contents will be updated as soon as they are released by the health department." -} diff --git a/citizen-portal/src/lib/baseModule/locales/en/imprint.json b/citizen-portal/src/lib/baseModule/locales/en/imprint.json deleted file mode 100644 index c574197ad9ce02e78613d1dc86c381139e6f6d6c..0000000000000000000000000000000000000000 --- a/citizen-portal/src/lib/baseModule/locales/en/imprint.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pageTitle": { - "imprint": "Imprint" - }, - "page_under_construction": "This page is currently under construction. The contents will be updated as soon as they are released by the health department." -} diff --git a/citizen-portal/src/lib/baseModule/locales/en/privacyPolicy.json b/citizen-portal/src/lib/baseModule/locales/en/privacyPolicy.json deleted file mode 100644 index 63a3e07eafb38d2cdf60e616f35e39655381fe5f..0000000000000000000000000000000000000000 --- a/citizen-portal/src/lib/baseModule/locales/en/privacyPolicy.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pageTitle": { - "privacy_policy": "Privacy policy" - }, - "page_under_construction": "This page is currently under construction. The contents will be updated as soon as they are released by the health department." -} diff --git a/citizen-portal/src/lib/baseModule/locales/en/termsOfUse.json b/citizen-portal/src/lib/baseModule/locales/en/termsOfUse.json deleted file mode 100644 index f525d5dae6f8c6935c28f319476495ff7684882e..0000000000000000000000000000000000000000 --- a/citizen-portal/src/lib/baseModule/locales/en/termsOfUse.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pageTitle": { - "terms_of_use": "Terms of use" - }, - "page_under_construction": "This page is currently under construction. The contents will be updated as soon as they are released by the health department." -} diff --git a/citizen-portal/src/lib/baseModule/locales/en/translation.json b/citizen-portal/src/lib/baseModule/locales/en/translation.json index 61330114748083cf8b44a1abf091310b5ae57905..c9a724bf2a254d39020e059a5e845be26dea6489 100644 --- a/citizen-portal/src/lib/baseModule/locales/en/translation.json +++ b/citizen-portal/src/lib/baseModule/locales/en/translation.json @@ -1,22 +1,19 @@ { "organization": { "landing_page": { - "header": "Welcome to the health department. ðŸ¢", - "subheader": "We look forward to welcoming you here. Our team is at your disposal to help you with all your questions and concerns in the field of public health. Your health is important to us and we are committed to your well-being with expertise and dedication.", - "contact_us": "Please do not hesitate to contact us if you need support or are looking for information on health-related topics. We will be happy to help and advise you." + "header": "Welcome to the health department.", + "subheader": "The {{name}} offers extensive services for the protection and restoration of health." } }, "private_person": { "landing_page": { - "header": "Welcome to the health department. ðŸ¢", - "subheader": "We look forward to welcoming you here. Our team is at your disposal to help you with all your questions and concerns in the field of public health. Your health is important to us and we are committed to your well-being with expertise and dedication.", - "contact_us": "Please do not hesitate to contact us if you need support or are looking for information on health-related topics. We will be happy to help and advise you." + "header": "Welcome to the health department.", + "subheader": "The {{name}} offers extensive services for the protection and restoration of health." } }, "site_title": "Online-Portal", "site_description": "Von Bürgern für Bürger", "health_department_title": "Health Department", - "health_officers_link": "Public Health Officers", "most_searched_services_title": "Most Search for Services", "common": { "address": "Address", diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/api/clients.ts b/citizen-portal/src/lib/businessModules/measlesProtection/api/clients.ts index a0f7c456f71d30183c929c1ba409f262e8e41342..6bd29a73723df94675774a25146cb3970f1bb3e2 100644 --- a/citizen-portal/src/lib/businessModules/measlesProtection/api/clients.ts +++ b/citizen-portal/src/lib/businessModules/measlesProtection/api/clients.ts @@ -5,6 +5,7 @@ import { Configuration, + FileApi, OrganisationPortalApi, } from "@eshg/citizen-portal-api/measlesProtection"; import { useApiConfiguration } from "@eshg/lib-portal/api/ApiProvider"; @@ -16,6 +17,11 @@ function useConfiguration() { return new Configuration(configurationParameters); } +export function useFileApi() { + const config = useConfiguration(); + return new FileApi(config); +} + export function useOrganisationPortalApi(): OrganisationPortalApi { return new OrganisationPortalApi(useConfiguration()); } diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/api/queries.ts b/citizen-portal/src/lib/businessModules/measlesProtection/api/queries.ts new file mode 100644 index 0000000000000000000000000000000000000000..e025f2f13f0184ad6cce98204c4ff89e0e510fe1 --- /dev/null +++ b/citizen-portal/src/lib/businessModules/measlesProtection/api/queries.ts @@ -0,0 +1,17 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useFileDownload } from "@eshg/lib-portal/api/files/download"; + +import { useOrganisationPortalApi } from "./clients"; + +export function usePrivacyNoticeFile() { + const orgApi = useOrganisationPortalApi(); + return useFileDownload(() => orgApi.getPrivacyNoticeRaw()); +} +export function usePrivacyPolicyFile() { + const orgApi = useOrganisationPortalApi(); + return useFileDownload(() => orgApi.getPrivacyPolicyRaw()); +} diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseForm.tsx b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseForm.tsx index 14c4431540e63f6cc6d5b5598b38e9d8fa05927b..4f673ef7171ed4d64357d4f6b7ce3cde601799e9 100644 --- a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseForm.tsx +++ b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseForm.tsx @@ -66,6 +66,8 @@ export const reportMeaslesCaseFormInitialValues: ReportMeaslesCase = { facility: facilityInitial, otherFacilityTypeInformation: "", type: "OTHER", + confirmPrivacyNotice: false, + confirmPrivacyPolicy: false, }; export const reportCaseFormPages = { diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseOverview.tsx b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseOverview.tsx index 03ab04dc11a74c060a626bf44cd1c671931f4576..028ab832a4ce77128a3ab7ea967d309069715b6e 100644 --- a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseOverview.tsx +++ b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseOverview.tsx @@ -67,15 +67,10 @@ function DetailsField({ interface ReportCaseOverviewProps { onCancel?: () => unknown; - onSubmit?: () => unknown; sx?: SxProps; } -export function ReportCaseOverview({ - onCancel, - onSubmit, - sx, -}: ReportCaseOverviewProps) { +export function ReportCaseOverview({ onCancel, sx }: ReportCaseOverviewProps) { const { t } = useTranslation(["measlesProtection/forms"]); const { values, setValues, isSubmitting } = useFormikContext<ReportMeaslesCase>(); @@ -286,7 +281,7 @@ export function ReportCaseOverview({ showFacilityContactPerson showAffected={{ count: true }} submitLabel={t("overview.submit", { count: affectedPersons.length })} - onSubmit={onSubmit} + finalSubmit={true} onCancel={onCancel} actionButton={ <Button variant="outlined" onClick={handleAddAffectedPerson}> diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseOverviewCard.tsx b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseOverviewCard.tsx index dee2e0c423105fa14a6f62a5a9409ff9930f191e..320b22f497cb27f2cfdc03818b634bde34899b55 100644 --- a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseOverviewCard.tsx +++ b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/ReportCaseOverviewCard.tsx @@ -7,6 +7,7 @@ import { ApiReportingReason, ApiRoleStatus, } from "@eshg/citizen-portal-api/measlesProtection"; +import { DownloadLink } from "@eshg/lib-portal/api/files/DownloadLink"; import { SubmitButton } from "@eshg/lib-portal/components/buttons/SubmitButton"; import { Business, @@ -20,13 +21,18 @@ import { import { Box, Button, Card, CardContent, Stack, Typography } from "@mui/joy"; import { SxProps } from "@mui/joy/styles/types"; import { useFormikContext } from "formik"; -import { ReactElement } from "react"; +import { ReactElement, ReactNode } from "react"; +import { + usePrivacyNoticeFile, + usePrivacyPolicyFile, +} from "@/lib/businessModules/measlesProtection/api/queries"; import { reportingReasonNames, roleStatusNames, } from "@/lib/businessModules/measlesProtection/shared/translations"; import { useTranslation } from "@/lib/i18n/client"; +import { ConfirmationCheckboxField } from "@/lib/shared/components/form/ConfirmationCheckboxField"; import { useSearchParam } from "@/lib/shared/hooks/useSearchParam"; import { formatAddress } from "./helpers"; @@ -55,7 +61,6 @@ const iconColor = "var(--joy-palette-text-primary)"; interface ReportCaseOverviewCardProps { onCancel?: () => unknown; - onSubmit?: () => unknown; actionButton?: ReactElement; cancelLabel?: string; facilityName: string; @@ -67,11 +72,11 @@ interface ReportCaseOverviewCardProps { }; submitDisabled?: boolean; submitLabel?: string; + finalSubmit?: boolean; } export function ReportCaseOverviewCard({ onCancel, - onSubmit, actionButton, cancelLabel, facilityName, @@ -81,6 +86,7 @@ export function ReportCaseOverviewCard({ count: false, current: false, }, + finalSubmit, submitDisabled = false, submitLabel, }: ReportCaseOverviewCardProps) { @@ -172,20 +178,99 @@ export function ReportCaseOverviewCard({ </Box> </> )} - <Stack gap={3}> - <SubmitButton - onClick={onSubmit} - submitting={isSubmitting} - disabled={submitDisabled} - > - {submitLabel ?? t("common.continue")} - </SubmitButton> - {actionButton} - <Button onClick={onCancel} variant="soft" color="neutral"> - {cancelLabel ?? t("common.cancel")} - </Button> - </Stack> + <ReportCaseOverviewCardButtons + affectedPersonCount={affectedPersons.length} + isSubmitting={isSubmitting} + submitDisabled={submitDisabled} + submitLabel={submitLabel} + onCancel={onCancel} + cancelLabel={cancelLabel} + actionButton={actionButton} + finalSubmit={finalSubmit} + /> </CardContent> </Card> ); } + +interface ReportCaseOverviewSubmitFormProps { + onSubmit?: () => unknown; + isSubmitting: boolean; + submitDisabled: boolean; + submitLabel?: string; + onCancel?: () => unknown; + cancelLabel?: string; + actionButton: ReactNode; + finalSubmit?: boolean; + affectedPersonCount: number; +} +function ReportCaseOverviewCardButtons({ + isSubmitting, + submitDisabled, + submitLabel, + finalSubmit, + onCancel, + cancelLabel, + actionButton, + affectedPersonCount, +}: ReportCaseOverviewSubmitFormProps) { + const { t } = useTranslation(); + + return ( + <Stack gap={2}> + {finalSubmit && ( + <DataAndPrivacySection affectedPersonCount={affectedPersonCount} /> + )} + <SubmitButton submitting={isSubmitting} disabled={submitDisabled}> + {submitLabel ?? t("common.continue")} + </SubmitButton> + {actionButton} + <Button onClick={onCancel} variant="soft" color="neutral"> + {cancelLabel ?? t("common.cancel")} + </Button> + </Stack> + ); +} + +function DataAndPrivacySection({ + affectedPersonCount, +}: { + affectedPersonCount: number; +}) { + const { t } = useTranslation("measlesProtection/forms"); + const privacyNoticeFile = usePrivacyNoticeFile(); + const privacyPolicyFile = usePrivacyPolicyFile(); + return ( + <Stack gap={2} mb={1}> + <p>{t("data_and_privacy.information", { count: affectedPersonCount })}</p> + <ConfirmationCheckboxField + name="confirmPrivacyNotice" + label={t("data_and_privacy.confirm_privacy_notice")} + required={t("data_and_privacy.confirm_required")} + descriptionText={ + <DownloadLink + downloadContainerRef={privacyNoticeFile.downloadContainerRef} + fontSize="sm" + onDownload={() => privacyNoticeFile.download()} + > + {t("data_and_privacy.privacy_notice")} + </DownloadLink> + } + /> + <ConfirmationCheckboxField + name="confirmPrivacyPolicy" + label={t("data_and_privacy.confirm_privacy_policy")} + required={t("data_and_privacy.confirm_required")} + descriptionText={ + <DownloadLink + downloadContainerRef={privacyPolicyFile.downloadContainerRef} + fontSize="sm" + onDownload={() => privacyPolicyFile.download()} + > + {t("data_and_privacy.privacy_policy")} + </DownloadLink> + } + /> + </Stack> + ); +} diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/AffectedPersonForm.tsx b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/AffectedPersonForm.tsx index a25fd75f354cf9f713b6b9c9346220b53f124a13..0fc90a67fba8ddcf2a08ebd08de85294a9a4265d 100644 --- a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/AffectedPersonForm.tsx +++ b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/AffectedPersonForm.tsx @@ -80,15 +80,10 @@ export function createEmptyAffectedPerson(): AffectedPersonFormInputs { interface AffectedPersonFormProps { onCancel?: () => unknown; - onSubmit?: () => unknown; sx?: SxProps; } -export function AffectedPersonForm({ - onCancel, - onSubmit, - sx, -}: AffectedPersonFormProps) { +export function AffectedPersonForm({ onCancel, sx }: AffectedPersonFormProps) { const { t } = useTranslation(["measlesProtection/forms"]); const { setFieldValue, @@ -249,7 +244,6 @@ export function AffectedPersonForm({ facilityName={facilityName} cancelLabel={t("common.back")} onCancel={onCancel} - onSubmit={onSubmit} showFacilityContactPerson /> </> diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/CustodianForm.tsx b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/CustodianForm.tsx index 87ed52b4f018d53cb3eace3995017b2114bffd5e..b5268377bc66b79aa264808a31b4cc427f9dcda6 100644 --- a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/CustodianForm.tsx +++ b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/CustodianForm.tsx @@ -187,14 +187,12 @@ export function CustodianForm({ interface CustodianFieldArrayProps extends NestedFormProps { onCancel?: () => unknown; - onSubmit?: () => unknown; custodianRequired?: boolean; sx?: SxProps; } export function CustodiansFieldArray({ onCancel, - onSubmit, name, sx, custodianRequired = true, @@ -350,7 +348,6 @@ export function CustodiansFieldArray({ isSubmitting={isSubmitting} facilityName={facilityName} cancelLabel={t("common.back")} - onSubmit={onSubmit} onCancel={onCancel} showFacilityContactPerson showAffected={{ current: true }} diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/FacilityForm.tsx b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/FacilityForm.tsx index 2742dab4b31b613ec9b3b44fea88cd1ed260b470..ad9e97713c0a11b06f565185bc398493a4e11847 100644 --- a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/FacilityForm.tsx +++ b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/subforms/FacilityForm.tsx @@ -43,16 +43,10 @@ export const facilityInitial: FacilityFormInputs = { interface FacilityFormProps extends NestedFormProps { onCancel?: () => unknown; - onSubmit?: () => unknown; sx?: SxProps; } -export function FacilityForm({ - onCancel, - onSubmit, - name, - sx, -}: FacilityFormProps) { +export function FacilityForm({ onCancel, name, sx }: FacilityFormProps) { const { isSubmitting, values: { @@ -109,7 +103,6 @@ export function FacilityForm({ <ReportCaseOverviewCard isSubmitting={isSubmitting} facilityName={facilityName} - onSubmit={onSubmit} onCancel={onCancel} /> </> diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/types.ts b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/types.ts index b904aa5f923cb5df4e7a1e6304894ee921d6d407..bdcd3d8985527902295fe4bed89fb9f8c376b839 100644 --- a/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/types.ts +++ b/citizen-portal/src/lib/businessModules/measlesProtection/components/reportCase/types.ts @@ -73,4 +73,6 @@ export interface ReportMeaslesCase facility: FacilityFormInputs; otherFacilityTypeInformation?: string; type: OptionalFieldValue<ApiMPFacilityType>; + confirmPrivacyNotice: boolean; + confirmPrivacyPolicy: boolean; } diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/locales/de/forms.json b/citizen-portal/src/lib/businessModules/measlesProtection/locales/de/forms.json index f2da8ba63c7aa2498199a7cddb5e42298aacaaf2..84f73a5abb5ad22a2742e060158911a2acdfda0f 100644 --- a/citizen-portal/src/lib/businessModules/measlesProtection/locales/de/forms.json +++ b/citizen-portal/src/lib/businessModules/measlesProtection/locales/de/forms.json @@ -82,5 +82,14 @@ "title": "Titel" }, "requiredField": "Pflichtfeld" + }, + "data_and_privacy": { + "information_one": "Um den Fall zu melden, müssen Sie erst folgenden Datenschutzverordnungen zustimmen.", + "information_other": "Um die Fälle zu melden, müssen Sie erst folgenden Datenschutzverordnungen zustimmen.", + "confirm_privacy_notice": "Ich akzeptiere den Datenschutzhinweis.", + "privacy_notice": "Zum Datenschutzhinweis", + "confirm_privacy_policy": "Ich akzeptiere die Datenschutzerklärung.", + "privacy_policy": "Zur Datenschutzerklärung", + "confirm_required": "Bitte Zustimmung erteilen um fortzufahren." } } diff --git a/citizen-portal/src/lib/businessModules/measlesProtection/locales/en/forms.json b/citizen-portal/src/lib/businessModules/measlesProtection/locales/en/forms.json index e5248feec006944264646c48589d93e12105fa4e..5e81c84e08277dd11ce9e0bdfb30b099d5ea1307 100644 --- a/citizen-portal/src/lib/businessModules/measlesProtection/locales/en/forms.json +++ b/citizen-portal/src/lib/businessModules/measlesProtection/locales/en/forms.json @@ -82,5 +82,14 @@ "title": "Title" }, "requiredField": "Required field" + }, + "data_and_privacy": { + "information_one": "To report this case, you must first agree to the following data protection regulations.", + "information_other": "To report these cases, you must first agree to the following data protection regulations.", + "confirm_privacy_notice": "I accept the privacy notice.", + "privacy_notice": "View Privacy Notice", + "confirm_privacy_policy": "I accept the privacy policy.", + "privacy_policy": "View Privacy Policy", + "confirm_required": "Please give your consent to continue." } } diff --git a/citizen-portal/src/lib/businessModules/schoolEntry/locales/de/overview.json b/citizen-portal/src/lib/businessModules/schoolEntry/locales/de/overview.json index 91a6a13b2398f805deb47e72c011858064850e1d..6379e4563059fa4d157488711fc117318b94d480 100644 --- a/citizen-portal/src/lib/businessModules/schoolEntry/locales/de/overview.json +++ b/citizen-portal/src/lib/businessModules/schoolEntry/locales/de/overview.json @@ -2,26 +2,24 @@ "pageTitle": "Einschulungsuntersuchung", "information": { "title": "Informationen zum Termin", - "invitation": "Den Termin zur Einschulungsuntersuchung verschickt das Gesundheitsamt per Post mit einem Einladungsschreiben und den aktuell geltenden Datenschutzrichtlinien etwa 3 bis 4 Wochen vor dem Termin.", - "cancellation": "Falls dieser Termin nicht wahrgenommen werden kann, sollte er rechtzeitig abgesagt werden. Die Kontaktdaten stehen auf dem Einladungsschreiben.", + "invitation": "Den Termin zur Einschulungsuntersuchung verschickt das Gesundheitsamt per Post mit einem Einladungsschreiben etwa 3 bis 4 Wochen vor dem Termin.", + "cancellation": "Falls dieser Termin nicht wahrgenommen werden kann, sollte er rechtzeitig verschoben werden. Dies können Sie hier über das Online-Portal bequem selbst erledigen. Mithilfe des Anmeldecodes auf der Einladung und dem Geburtstag Ihres Kindes erreichen Sie Ihren persönlichen Bereich.", "location": "Die Einschulungsuntersuchung findet im Gesundheitsamt in der {{address}} statt. Bitte im Eingangsbereich am Empfang melden und das Einladungsschreiben vorzeigen." }, "place": { - "title": "Wo findet die Einschulungsuntersuchung statt?", - "school": "In der Schule ihres Kindes", - "or": "oder", - "healthDepartment": "in folgendem Gesundheitsamt" + "title": "Wo findet die Einschulungsuntersuchung statt?" }, "address": { "title": "Adresse" }, "openingHours": { "title": "Öffnungs- und Sprechzeiten", - "days": "Mo, Di, Do", - "daysHoliday": "Di, Do", - "hours": "13:30 - 15:00 Uhr", + "days": "Mo - Do", + "daysShort": "Fr", + "hours": "07:30 - 16:00 Uhr", "remark": "Nur nach Terminabsprache.", - "remarkHoliday": "In den hessischen Schulferien – Nur nach Terminabsprache." + "hoursShort": "07:30 - 14:00 Uhr", + "remarkShort": "Nur nach Terminabsprache." }, "telefon": { "title": "Telefon", diff --git a/citizen-portal/src/lib/businessModules/schoolEntry/locales/en/overview.json b/citizen-portal/src/lib/businessModules/schoolEntry/locales/en/overview.json index 7718965bd99d60966e6d61f07471bc6518bf5ff6..e6e8e35398313b90c173a34c485e24be29e2c6d7 100644 --- a/citizen-portal/src/lib/businessModules/schoolEntry/locales/en/overview.json +++ b/citizen-portal/src/lib/businessModules/schoolEntry/locales/en/overview.json @@ -2,26 +2,24 @@ "pageTitle": "School Entry Examination", "information": { "title": "Information about the Appointment", - "invitation": "The Health Department will send the appointment for the school enrollment examination by mail with an invitation letter and the currently applicable data protection regulations approximately 3 to 4 weeks before the appointment.", - "cancellation": "If this appointment cannot be kept, it should be canceled in good time. The contact details are provided in the invitation letter.", - "location": "The school enrollment examination takes place at the Health Department at {{address}}. Please report to the reception area at the entrance and present the invitation letter." + "invitation": "The appointment for the school enrollment examination is sent by mail from the health department along with an invitation letter approximately 3 to 4 weeks before the appointment.", + "cancellation": "If you are unable to attend this appointment, it should be rescheduled in a timely manner. You can conveniently do this yourself here via the online portal. Using the registration code on the invitation and your child's date of birth, you can access your personal area.", + "location": "The school enrollment examination takes place at the health department at {{address}}. Please report to the reception at the entrance and present the invitation letter." }, "place": { - "title": "Where does the school enrollment examination take place?", - "school": "At your child's school", - "or": "or", - "healthDepartment": "at the following Health Department" + "title": "Where does the school enrollment examination take place?" }, "address": { "title": "Address" }, "openingHours": { "title": "Opening and Consultation Hours", - "days": "Mon, Tue, Thu", - "daysHoliday": "Tue, Thu", - "hours": "1:30 PM - 3:00 PM", - "remark": "By appointment only", - "remarkHoliday": "During Hessian school holidays – By appointment only." + "days": "Mon - Thu", + "daysShort": "Fri", + "hours": "07:30 AM - 4:00 PM", + "remark": "By appointment only.", + "hoursShort": "07:30 AM - 2:00 PM", + "remarkShort": "By appointment only." }, "telefon": { "title": "Phone", @@ -31,12 +29,12 @@ "title": "Email Address" }, "personalArea": { - "title": "Did you receive an invitation?", + "title": "Have you received an invitation?", "information": "To view your appointment, you must first agree to the following data protection regulations.", - "confirmPrivacyNotice": "I accept the privacy notice.", - "privacyNotice": "View Privacy Notice", + "confirmPrivacyNotice": "I accept the data protection notice.", + "privacyNotice": "Go to the data protection notice", "confirmPrivacyPolicy": "I accept the privacy policy.", - "privacyPolicy": "View Privacy Policy", - "goToPersonalArea": "View Invitation" + "privacyPolicy": "Go to the privacy policy", + "goToPersonalArea": "View invitation" } } diff --git a/citizen-portal/src/lib/businessModules/schoolEntry/pages/landingpage/LandingpageContent.tsx b/citizen-portal/src/lib/businessModules/schoolEntry/pages/landingpage/LandingpageContent.tsx index 1edb09a31c107f2ce5a2552aebbe8964250227a9..1b555b44d974ba1f507a963825842a052504b384 100644 --- a/citizen-portal/src/lib/businessModules/schoolEntry/pages/landingpage/LandingpageContent.tsx +++ b/citizen-portal/src/lib/businessModules/schoolEntry/pages/landingpage/LandingpageContent.tsx @@ -10,7 +10,7 @@ import { FmdGoodOutlined, MailOutlineOutlined, } from "@mui/icons-material"; -import { Stack, Typography } from "@mui/joy"; +import { Typography } from "@mui/joy"; import { useTranslation } from "@/lib/i18n/client"; import { DepartmentInfo } from "@/lib/shared/api/models/DepartmentInfo"; @@ -55,13 +55,6 @@ export function LandingpageContent(props: LandingpageContentProps) { </ContentSheet> <ContentSheet> <ContentSheetTitle>{t("place.title")}</ContentSheetTitle> - <Stack component={Typography} gap={1}> - <Typography fontWeight="bold">{t("place.school")}</Typography> - <Typography>{t("place.or")}</Typography> - <Typography fontWeight="bold"> - {t("place.healthDepartment")} - </Typography> - </Stack> <InfoSectionGrid> <AddressSection department={props.departmentInfo} /> <OpeningHoursSection /> @@ -100,8 +93,10 @@ function OpeningHoursSection() { <br /> {t("openingHours.remark")} </TableListingRow> - <TableListingRow label={t("openingHours.daysHoliday")}> - {t("openingHours.remarkHoliday")} + <TableListingRow label={t("openingHours.daysShort")}> + {t("openingHours.hoursShort")} + <br /> + {t("openingHours.remarkShort")} </TableListingRow> </TableListing> </InfoSection> diff --git a/citizen-portal/src/lib/businessModules/travelMedicine/components/landing/LandingpageContent.tsx b/citizen-portal/src/lib/businessModules/travelMedicine/components/landing/LandingpageContent.tsx index ed2d7d946fc2f0007e9095c83fdf98527721b1e9..07018513e50ba4fb7748254fc628f8339a07272a 100644 --- a/citizen-portal/src/lib/businessModules/travelMedicine/components/landing/LandingpageContent.tsx +++ b/citizen-portal/src/lib/businessModules/travelMedicine/components/landing/LandingpageContent.tsx @@ -22,6 +22,10 @@ import { ContentSheetTitle, } from "@/lib/shared/components/layout/contentSheet"; import { GridColumnStack } from "@/lib/shared/components/layout/grid"; +import { + TableListing, + TableListingRow, +} from "@/lib/shared/components/tableListing"; import { formatPostalCodeAndCity, formatStreetAndHouseNumber, @@ -38,8 +42,8 @@ export function LandingpageContent() { <InfoSectionGrid> <AddressSection department={department} /> <ContactDataSection department={department} /> - <OpeningHoursSection /> </InfoSectionGrid> + <OpeningHoursSection /> </ContentSheet> </GridColumnStack> ); @@ -64,10 +68,22 @@ function OpeningHoursSection() { return ( <InfoSection icon={<AccessTimeOutlined />}> <InfoSectionTitle>Öffnungszeiten</InfoSectionTitle> - <Typography> - Für einzelne Bereiche und Beratungsstellen gelten unterschiedliche - Sprechzeiten. - </Typography> + <TableListing> + <tr> + <td colSpan={2} style={{ paddingBottom: 3 }}> + Sprechzeiten nur nach Terminvereinbarung (telefonisch oder per + E-Mail) + </td> + </tr> + <TableListingRow label="Mo bis Do">08:00 bis 12:00 Uhr</TableListingRow> + <tr> + <td colSpan={2} style={{ paddingTop: 3, paddingBottom: 3 }}> + Telefonische Terminvereinbarung + </td> + </tr> + <TableListingRow label="Mo bis Mi">14:00 bis 15:00 Uhr</TableListingRow> + <TableListingRow label="Fr">08:00 bis 10:00 Uhr</TableListingRow> + </TableListing> </InfoSection> ); } diff --git a/citizen-portal/src/lib/businessModules/travelMedicine/locales/en/appointmentDetails.json b/citizen-portal/src/lib/businessModules/travelMedicine/locales/en/appointmentDetails.json new file mode 100644 index 0000000000000000000000000000000000000000..2e610c07f0c03242159447a7a4d2f435e6a83941 --- /dev/null +++ b/citizen-portal/src/lib/businessModules/travelMedicine/locales/en/appointmentDetails.json @@ -0,0 +1,32 @@ +{ + "header": { + "title": "Mein Termin", + "logout": "Mein Bereich verlassen" + }, + "title": "Informationen", + "sidePanel": { + "title": "Sie können den Termin nicht wahrnehmen?", + "postponeAppointment": "Termin verschieben", + "cancelAppointment": "Termin absagen", + "back": "Zurück" + }, + "appointmentType": { + "consultation": "Reiseberatung", + "vaccination": "Impfung" + }, + "start": "{{ time }} Uhr", + "duration": "Dauer: {{ appointmentDuration }} Minuten", + "medicalHistoryPanel": { + "title": "Vorbereitung zum Termin", + "medicalHistorySheet": "Anamnesebogen", + "notAnswered": "noch nicht vorgelegt", + "answered": "erfolgreich übermittelt", + "answerNow": "Jetzt ausfüllen", + "neededDocuments": "Benötigte Unterlagen", + "filledMedicalHistory": "ausgefüllter Anamnesebogen", + "vaccinationCertificate": "Impfausweis", + "uBooklet": "das gelbe Vorsorgeheft (U-Heft)", + "medicalDocuments": "gegebenenfalls weitere medizinische Unterlagen, evtl. aktuelle Medikation", + "otherTools": "gegebenenfalls vorhandene Hilfsmittel (Brille, Hörgerät)" + } +} diff --git a/citizen-portal/src/lib/businessModules/travelMedicine/locales/en/appointmentOverview.json b/citizen-portal/src/lib/businessModules/travelMedicine/locales/en/appointmentOverview.json new file mode 100644 index 0000000000000000000000000000000000000000..c0e1c25841af53617410d93430bcaaae29a8ec0b --- /dev/null +++ b/citizen-portal/src/lib/businessModules/travelMedicine/locales/en/appointmentOverview.json @@ -0,0 +1,27 @@ +{ + "header": { + "title": "Termine", + "logout": "Mein Bereich verlassen" + }, + "typeSwitchButtons": { + "upcoming": "Anstehende", + "past": "Vergangene" + }, + "appointmentCard": { + "start": "{{ time }} Uhr", + "duration": "Dauer: {{ appointmentDuration }} Minuten", + "appointmentType": { + "consultation": "Reiseberatung", + "vaccination": "Impfung" + } + }, + "appointmentStatus": { + "booked": "Termin gebucht" + }, + "noAppointments": { + "upcomingAppointments": "Anstehende Termine", + "pastAppointments": "Vergangene Termine", + "noUpcomingAppointments": "Keine anstehende Termine", + "noPastAppointments": "Keine vergangene Termine" + } +} diff --git a/citizen-portal/src/lib/businessModules/travelMedicine/locales/en/forms.json b/citizen-portal/src/lib/businessModules/travelMedicine/locales/en/forms.json new file mode 100644 index 0000000000000000000000000000000000000000..0b44d0e6e4fc2e618f7bd7285b97ba413c63fb9c --- /dev/null +++ b/citizen-portal/src/lib/businessModules/travelMedicine/locales/en/forms.json @@ -0,0 +1,125 @@ +{ + "common": { + "title": "Reisemedizinische Impfberatung", + "requiredTitle": "*Pflichtfeld", + "stepperTitle": "Schritt {{currentStepIndex}} von {{totalSteps}}" + }, + "appointmentTypeFormContent": { + "title": "Terminart", + "infoHeader": "Wichtige Informationen zum Termin", + "infoTextListItem1": "Bitte bringen Sie Ihre Impfpass mit.", + "infoTextListItem2": "Für größere Gruppen (mehr als 3 Personen) nutzen Sie bitte die telefonische Terminvereinbarung unter {{ phoneNumber }}.", + "confirmation": { + "label": "Beglaubigung/Apostille ", + "subtitle": "(Offene Sprechstunde)", + "info": "Nur telefonisch unter {{ phoneNumber }} buchbar:", + "iconLabel": "Information zu $t(appointmentTypeFormContent.confirmation.label)", + "modalTitle": "$t(appointmentTypeFormContent.confirmation.label)", + "modalTextParagraph1": "Termindauer für Beratungsgespräche in der Regel ca. 30 Minuten.", + "modalTextParagraph2": "Bitte Impfpass mitbringen." + }, + "fields": { + "error": "Bitte Terminart auswählen.", + "vaccination": { + "label": "Impfung", + "iconLabel": "Information zu $t(appointmentTypeFormContent.fields.vaccination.label)", + "modalTitle": "$t(appointmentTypeFormContent.fields.vaccination.label)", + "modalTextParagraph1": "Termindauer für Impfungen in der Regel ca. 15 Minuten. Auffrischungsimpfungen oder Folgeimpfungen nach erfolgter Erstberatung.", + "modalTextParagraph2": "Bitte Impfpass mitbringen." + }, + "consultation": { + "label": "Reiseberatung", + "iconLabel": "Information zu $t(appointmentTypeFormContent.fields.consultation.label)", + "modalTitle": "$t(appointmentTypeFormContent.fields.consultation.label)", + "modalTextParagraph1": "Termindauer für Beratungsgespräche in der Regel ca. 30 Minuten. Reisemedizinische Beratung mit oder ohne anschließenden Impfungen.", + "modalTextParagraph2": "Bitte Impfpass mitbringen." + } + } + }, + "appointmentSlotFormContent": { + "title": "Verfügbare Termine", + "fields": { + "appointmentStart": "Termin", + "appointmentStart_required": "Bitte einen Termin auswählen." + }, + "appointmentPicker": { + "noAppointmentForSelectedDate": " Für den ausgewählten Tag stehen keine freien Termine zur Verfügung", + "noAppointmentSelected": "Es wurde kein Termin ausgewählt", + "noAppointmentsAvailable": "Derzeit sind keine Termine verfügbar", + "tryLater": "Wir schalten in kürze Termine frei. Bitte versuchen Sie es zu einem späteren Zeitpunkt erneut", + "calendar_title": "Datum", + "timePicker_title": "Verfügbare Uhrzeiten", + "available": "Verfügbar" + }, + "backToOverview": "Zurück zur Ãœbersicht" + }, + "travelTypeFormContent": { + "title": "Reiseart", + "error": "Bitte Reiseart auswählen.", + "fields": {} + }, + "travelDataFormContent": { + "title": "Reisedaten", + "fields": { + "travelDestinations": "Reiseziele", + "travelDestinations_required": "Bitte Reiseziel eingeben.", + "travelStartDate": "Reisebeginn", + "travelStartDate_required": "Bitte Reisebeginn eingeben.", + "travelTimeAmount": "Reisedauer", + "travelTimeAmount_required": "Bitte Reisedauer eingeben.", + "travelTimeUnit": "Reisedauereinheit", + "travelTimeUnit_required": "Bitte Reisedauereinheit eingeben." + } + }, + "personalDataFormContent": { + "title": "Persönliche Daten", + "fields": { + "firstName": "Vorname", + "firstName_required": "Bitte Vorname eingeben.", + "lastName": "Nachname", + "lastName_required": "Bitte Nachname eingeben.", + "dateOfBirth": "Geburtsdatum", + "dateOfBirth_required": "Bitte Geburtsdatum eingeben.", + "phoneNumbers": "Telefon", + "emailAddresses": "E-Mail-Adresse", + "emailAddresses_required": "Bitte E-Mail-Adresse eingeben.", + "confirmOnlineServices": "Ich bestätige, dass ich die Online-Dienste für die Impfberatung nutzen und die hierzu notwendigen E-Mails erhalten möchte.", + "confirmOnlineServices_required": "Bitte Zustimmung erteilen um fortzufahren." + } + }, + "vaccinationFormContent": { + "title": "Impfungen", + "fields": {} + }, + "appointmentInfoSection": { + "title": "Informationen zum Termin", + "alertHeader": "Vorbereitungen zum Termin", + "alertMessage": "Bitte bringen Sie ihren Impfpass mit", + "infoText": "" + }, + "appointmentOverviewSection": { + "title": "Ãœbersicht", + "onNextStep": "Weiter", + "onPrevStep": "Zurück", + "onCancel": "Abbrechen", + "values": { + "confirmOnlineServices": "Bestätigungsmail senden", + "travelDuration": "Reisedauer", + "travelDestinations_one": "Reiseziel", + "travelDestinations_other": "Reiseziele", + "travelStartDate": "Reisebeginn" + } + }, + "confirmationSection": { + "title": "Terminbuchung", + "submit": "Termin verbindlich buchen", + "onPrevStep": "Zurück", + "onCancel": "Abbrechen", + "fields": { + "confirmPrivacyPolicy": "Ich akzeptiere den Datenschutzhinweis.", + "confirmPrivacyPolicy_required": "Bitte Zustimmung erteilen um fortzufahren.", + "confirmPrivacyNotice": "Ich akzeptiere die Datenschutzerklärung.", + "confirmPrivacyNotice_required": "Bitte Zustimmung erteilen um fortzufahren." + } + } +} diff --git a/citizen-portal/src/lib/i18n/components/LanguagePicker.tsx b/citizen-portal/src/lib/i18n/components/LanguagePicker.tsx index 4ee77d16ba707c97a6d7febfb25f34bf98e3064c..39162615f9f8a1a9f3007a207ca57fbdf95d3e72 100644 --- a/citizen-portal/src/lib/i18n/components/LanguagePicker.tsx +++ b/citizen-portal/src/lib/i18n/components/LanguagePicker.tsx @@ -23,7 +23,7 @@ import { styled, } from "@mui/joy"; import { TOptions } from "i18next"; -import { usePathname } from "next/navigation"; +import { usePathname, useSearchParams } from "next/navigation"; import { useRef } from "react"; import { useTranslation } from "@/lib/i18n/client"; @@ -52,7 +52,11 @@ export function LanguagePicker() { return ( <Dropdown> - <MenuButton ref={toggleButton} {...buttonStyling}> + <MenuButton + ref={toggleButton} + data-testId="languagePicker" + {...buttonStyling} + > {currentLanguage.name} </MenuButton> <Menu @@ -159,13 +163,20 @@ type LanguageOptionType = function LanguageOption({ option }: { option: LanguageOptionType }) { const pathname = usePathname(); + const searchParams = useSearchParams(); const givenLocale = useGivenLang(); + let newPath = pathname; if (givenLocale !== option.shortCode) { const parts = pathname.split("/"); const newParts = parts.slice(givenLocale === undefined ? 1 : 2); newPath = ["", option.shortCode, ...newParts].join("/"); } + + if (searchParams.size > 0) { + newPath = `${newPath}?${searchParams.toString()}`; + } + return ( <MenuItem component={NavigationLink} diff --git a/citizen-portal/src/lib/shared/components/CitizenSnackbar.tsx b/citizen-portal/src/lib/shared/components/CitizenSnackbar.tsx index eacaf09ca60fb082035cf760cc19532ab367ab17..bc425706cbf9052981ad804a87f57b4b2ec4cc2c 100644 --- a/citizen-portal/src/lib/shared/components/CitizenSnackbar.tsx +++ b/citizen-portal/src/lib/shared/components/CitizenSnackbar.tsx @@ -9,7 +9,6 @@ import { SnackbarComponentProps } from "@eshg/lib-portal/components/snackbar/Sna import { Check, Info, SvgIconComponent, Warning } from "@mui/icons-material"; import { Snackbar, Theme, styled } from "@mui/joy"; -import { responsiveContent } from "@/lib/baseModule/components/layout/Content"; import { ContentMargin, contentMarginDesktop, @@ -17,6 +16,7 @@ import { headerHeightDesktop, headerHeightMobile, } from "@/lib/baseModule/components/layout/sizes"; +import { responsiveContent } from "@/lib/shared/components/layout/PageContent"; const ICONS: Record<SnackbarComponentProps["color"], SvgIconComponent> = { primary: Info, diff --git a/citizen-portal/src/lib/shared/components/card/ServiceCardContainer.tsx b/citizen-portal/src/lib/shared/components/card/ServiceCardContainer.tsx index 8ec98d03dc299a62544e6b409cba88284aebb45b..ef69a4b888bdf4f5945f4a67d38e288dbb31634b 100644 --- a/citizen-portal/src/lib/shared/components/card/ServiceCardContainer.tsx +++ b/citizen-portal/src/lib/shared/components/card/ServiceCardContainer.tsx @@ -7,13 +7,11 @@ import { MedicalServicesOutlined, - PeopleOutlineOutlined, PhoneInTalkOutlined, } from "@mui/icons-material"; import { Typography } from "@mui/joy"; import { NavigationItem } from "@/lib/baseModule/components/layout/types"; -import { useRoutes as useBaseRoutes } from "@/lib/baseModule/shared/routes"; import { useCitizenRoutes as useSchoolEntryCitizenRoutes } from "@/lib/businessModules/schoolEntry/shared/routes"; import { useCitizenRoutes as useTravelMedicineRoutes } from "@/lib/businessModules/travelMedicine/shared/routes"; import { useTranslation } from "@/lib/i18n/client"; @@ -22,7 +20,6 @@ import { ServiceCard } from "@/lib/shared/components/card/ServiceCard"; export function useMostSearchedCitizenServices(): NavigationItem { const schoolEntryCitizenRoutes = useSchoolEntryCitizenRoutes(); const travelMedicineRoutes = useTravelMedicineRoutes(); - const baseRoutes = useBaseRoutes(); const { t } = useTranslation(); return { @@ -38,11 +35,6 @@ export function useMostSearchedCitizenServices(): NavigationItem { href: travelMedicineRoutes.overview, icon: PhoneInTalkOutlined, }, - { - name: t("health_officers_link"), - href: baseRoutes.citizenPath.index, - icon: PeopleOutlineOutlined, - }, ], }; } @@ -53,7 +45,7 @@ export function ServiceCardContainer({ navigationItem: NavigationItem; }) { return ( - <div style={{ display: "flex", alignItems: "center", margin: "56px 0px" }}> + <div style={{ display: "flex", alignItems: "center" }}> <div style={{ width: "100%" }}> <Typography level="h2">{navigationItem.name}</Typography> <div diff --git a/citizen-portal/src/lib/shared/components/form/ConfirmationCheckboxField.tsx b/citizen-portal/src/lib/shared/components/form/ConfirmationCheckboxField.tsx index 0c1d3ce7ccffcb029f1f90df9a00d986500d1b9c..f9ea4f1d458e3a825650eff0ffd6d29d01823696 100644 --- a/citizen-portal/src/lib/shared/components/form/ConfirmationCheckboxField.tsx +++ b/citizen-portal/src/lib/shared/components/form/ConfirmationCheckboxField.tsx @@ -33,7 +33,7 @@ export function ConfirmationCheckboxField( const { input, error, helperText } = useBaseField<boolean>({ type: "checkbox", name: props.name, - validate: validateChecked, + validate: createValueCheckedValidation(props.required), }); const isServer = useIsServer(); @@ -47,7 +47,7 @@ export function ConfirmationCheckboxField( variant="outlined" color="primary" disabled={isServer} - required + required={props.required != null} slots={{ label: RequiredFormLabel, // Joy UI does not pass required flag to checkbox labels }} @@ -66,10 +66,14 @@ function RequiredFormLabel(props: FormLabelProps) { return <FormLabel {...props} required />; } -function validateChecked(value: boolean) { - if (value) { - return undefined; - } +function createValueCheckedValidation( + requiredText = "Bitte Zustimmung erteilen um fortzufahren.", +) { + return (value: boolean) => { + if (value) { + return undefined; + } - return "Bitte Zustimmung erteilen um fortzufahren."; + return requiredText; + }; } diff --git a/citizen-portal/src/lib/baseModule/components/layout/PageBanner.tsx b/citizen-portal/src/lib/shared/components/layout/PageBanner.tsx similarity index 56% rename from citizen-portal/src/lib/baseModule/components/layout/PageBanner.tsx rename to citizen-portal/src/lib/shared/components/layout/PageBanner.tsx index 9f605700f0f378cd9666daf27a13faea9a9f1888..a78c52be0ddc96cc3a9780b4c8355e892ec8bbf7 100644 --- a/citizen-portal/src/lib/baseModule/components/layout/PageBanner.tsx +++ b/citizen-portal/src/lib/shared/components/layout/PageBanner.tsx @@ -1,15 +1,34 @@ /** * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only + * SPDX-License-Identifier: Apache-2.0 */ -import { Box, Typography, useTheme } from "@mui/joy"; +import { Box, Typography, styled, useTheme } from "@mui/joy"; -import { Content } from "@/lib/baseModule/components/layout/Content"; import { useTranslation } from "@/lib/i18n/client"; import { useGetDepartmentInfo } from "@/lib/shared/api/queries/department"; +import { PageContent } from "@/lib/shared/components/layout/PageContent"; -export function PageBanner() { +export type BannerType = "private" | "business" | "general"; + +interface PageBannerProps { + type: BannerType; +} + +const BannerPicture = styled("picture")({ + zIndex: -1, + position: "absolute", + width: "100%", + height: "100%", +}); + +const BannerImage = styled("img")({ + width: "100%", + height: "100%", + objectFit: "cover", +}); + +export function PageBanner(props: PageBannerProps) { const theme = useTheme(); const { t } = useTranslation(); const { data: department } = useGetDepartmentInfo(); @@ -19,15 +38,32 @@ export function PageBanner() { sx={{ height: 320, display: "flex", + flexDirection: "column", alignItems: "center", + justifyContent: "center", width: "100%", position: "relative", [theme.breakpoints.down("md")]: { - height: "124px", + height: 124, }, + overflow: "hidden", }} > - <Content> + <BannerPicture> + <source + srcSet={`/${props.type}Banner3460x640.png`} + media="(min-width: 1731px)" + /> + <source + srcSet={`/${props.type}Banner1730x320.png`} + media="(min-width: 721px)" + /> + <BannerImage + src={`/${props.type}Banner720x248.png`} + aria-hidden="true" + /> + </BannerPicture> + <PageContent> <Box sx={{ display: "flex", @@ -46,7 +82,10 @@ export function PageBanner() { > <Typography sx={{ - backgroundImage: `linear-gradient(93.08deg, rgba(128, 120, 255, 0.9) 0.43%, rgba(11, 107, 203, 0.9) 33.45%, rgba(51, 154, 254, 0.9) 57.18%, rgba(28, 224, 253, 0.9) 84.52%)`, + backgroundImage: + props.type === "general" + ? `linear-gradient(93.08deg, rgba(128, 120, 255, 0.9) 0.43%, rgba(11, 107, 203, 0.9) 33.45%, rgba(51, 154, 254, 0.9) 57.18%, rgba(28, 224, 253, 0.9) 84.52%)` + : `linear-gradient(89.95deg, #0B9DA6 0.09%, #00B8EC 50.5%, #7FC078 99.91%)`, backgroundSize: "100%", backgroundRepeat: "repeat", backgroundClip: "text", @@ -61,7 +100,7 @@ export function PageBanner() { > {t("health_department_title")} </Typography> - <Box display="flex" justifyContent="space-between"> + <Box display="flex"> <Box /> <Typography component="span" @@ -78,7 +117,7 @@ export function PageBanner() { </Box> </h1> </Box> - </Content> + </PageContent> </Box> ); } diff --git a/citizen-portal/src/lib/baseModule/components/layout/Content.tsx b/citizen-portal/src/lib/shared/components/layout/PageContent.tsx similarity index 55% rename from citizen-portal/src/lib/baseModule/components/layout/Content.tsx rename to citizen-portal/src/lib/shared/components/layout/PageContent.tsx index e23c8961ead301f4ce2c8c6f13586e00a85867c1..4730707fc39ce5b4e0285436ae49c095ac26e361 100644 --- a/citizen-portal/src/lib/baseModule/components/layout/Content.tsx +++ b/citizen-portal/src/lib/shared/components/layout/PageContent.tsx @@ -1,17 +1,18 @@ /** * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only + * SPDX-License-Identifier: Apache-2.0 */ -import { Box, useTheme } from "@mui/joy"; +"use client"; + +import { styled } from "@mui/joy"; import { SxProps, Theme } from "@mui/joy/styles/types"; -import { PropsWithChildren } from "react"; import { contentMarginDesktop, contentMarginMobile, maxContentWidthDesktop, -} from "./sizes"; +} from "@/lib/baseModule/components/layout/sizes"; declare module "@mui/system" { interface BreakpointOverrides { @@ -20,40 +21,33 @@ declare module "@mui/system" { } } -export function Content({ children }: PropsWithChildren) { - const theme = useTheme(); - - return ( - <Box - sx={{ - display: "flex", - width: "100%", - justifyContent: "center", - boxSizing: "content-box", - }} - > - <Box - sx={{ - margin: theme.spacing( - contentMarginDesktop.topBottom, - contentMarginDesktop.leftRight, - ), - ...responsiveContent(theme, { - sm: { - margin: theme.spacing( - contentMarginMobile.topBottom, - contentMarginMobile.leftRight, - ), - }, - }), - }} - > - {children} - </Box> - </Box> - ); +interface PageContentProps { + spacing?: "md" | "lg"; + fullHeight?: boolean; } +export const PageContent = styled("div", { + shouldForwardProp: (prop) => prop !== "spacing" && prop !== "fullHeight", +})<PageContentProps>(({ theme, spacing, fullHeight }) => ({ + flex: fullHeight ? 1 : undefined, + display: "flex", + flexDirection: "column", + gap: theme.spacing(spacing === "lg" ? 5 : contentMarginDesktop.topBottom), + paddingBlock: theme.spacing( + spacing === "lg" ? 5 : contentMarginDesktop.topBottom, + contentMarginDesktop.leftRight, + ), + ...responsiveContent(theme, { + sm: { + gap: theme.spacing(contentMarginMobile.topBottom), + paddingBlock: theme.spacing( + contentMarginMobile.topBottom, + contentMarginMobile.leftRight, + ), + }, + }), +})); + const ContentBreakpoints = { XL: "xl", LG: "lg", diff --git a/citizen-portal/src/lib/shared/components/layout/TitleAndSheetContentLayout.tsx b/citizen-portal/src/lib/shared/components/layout/TitleAndSheetContentLayout.tsx index 9335ba8aa8ac4a1a4dacf3cc3fec14195d5f2f88..9e7c9445fb47c5cfc5ae7f0fc14a1b573499d1bf 100644 --- a/citizen-portal/src/lib/shared/components/layout/TitleAndSheetContentLayout.tsx +++ b/citizen-portal/src/lib/shared/components/layout/TitleAndSheetContentLayout.tsx @@ -5,21 +5,23 @@ import { PropsWithChildren } from "react"; -import { PageBanner } from "@/lib/baseModule/components/layout/PageBanner"; import { ContentSheet } from "@/lib/shared/components/layout/contentSheet"; import { GridColumnStack } from "@/lib/shared/components/layout/grid"; -import { Page, PageTitle } from "@/lib/shared/components/layout/page"; + +import { PageContent } from "./PageContent"; +import { PageLayout, PageTitle } from "./page"; export function TitleAndSheetContentLayout( props: PropsWithChildren<{ pageTitle: string }>, ) { return ( - <Page> - <PageBanner /> - <PageTitle>{props.pageTitle}</PageTitle> - <GridColumnStack> - <ContentSheet>{props.children}</ContentSheet> - </GridColumnStack> - </Page> + <PageLayout> + <PageContent> + <PageTitle>{props.pageTitle}</PageTitle> + <GridColumnStack> + <ContentSheet>{props.children}</ContentSheet> + </GridColumnStack> + </PageContent> + </PageLayout> ); } diff --git a/citizen-portal/src/lib/shared/components/layout/page.tsx b/citizen-portal/src/lib/shared/components/layout/page.tsx index 0f5c3df77f65bc79dfc883c1a18f4dbe7950d93b..2cb3493786b4a5b01087685aa13dab61eecb4fcc 100644 --- a/citizen-portal/src/lib/shared/components/layout/page.tsx +++ b/citizen-portal/src/lib/shared/components/layout/page.tsx @@ -3,14 +3,46 @@ * SPDX-License-Identifier: Apache-2.0 */ +"use client"; + +import { + ScopedAlert, + useAlert, +} from "@eshg/lib-portal/errorHandling/AlertContext"; import { RequiresChildren } from "@eshg/lib-portal/types/react"; -import { Sheet, Stack, Typography } from "@mui/joy"; +import { Sheet, Stack, Typography, styled } from "@mui/joy"; import { ReactNode } from "react"; +import { isDefined } from "remeda"; import { theme } from "@/lib/baseModule/theme/theme"; -export function Page(props: RequiresChildren) { - return <Stack gap={3}>{props.children}</Stack>; +import { BannerType, PageBanner } from "./PageBanner"; +import { PageContent } from "./PageContent"; + +const MainContents = styled("main")({ + display: "contents", +}); + +interface PageLayoutProps extends RequiresChildren { + banner?: BannerType; +} + +export function PageLayout(props: PageLayoutProps) { + const alert = useAlert(); + + return ( + <> + {isDefined(props.banner) && <PageBanner type={props.banner} />} + <MainContents> + {alert !== null && ( + <PageContent> + <ScopedAlert /> + </PageContent> + )} + {props.children} + </MainContents> + </> + ); } interface PageTitleProps extends RequiresChildren { diff --git a/citizen-portal/src/lib/styles.ts b/citizen-portal/src/lib/styles.ts deleted file mode 100644 index 50d6c7bd2a318fe66853c79dffc040c075b4ab8c..0000000000000000000000000000000000000000 --- a/citizen-portal/src/lib/styles.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { SxProps } from "@mui/joy/styles/types"; - -export const PAGE_ALERT_STYLE: SxProps = { - marginBlockEnd: 3, -}; diff --git a/employee-portal/README.adoc b/employee-portal/README.adoc index 6181fa7483d0af2a6fa48932caffd2ce41607ca7..c0517643496436c7b0185a122412b0c3f3600e59 100644 --- a/employee-portal/README.adoc +++ b/employee-portal/README.adoc @@ -1,4 +1,4 @@ = Employee Portal :sectnums: -See link:../docs/frontend[here]. \ No newline at end of file +See link:../docs/frontend.adoc[here]. \ No newline at end of file diff --git a/employee-portal/src/app/(baseModule)/account/login-protocol/page.tsx b/employee-portal/src/app/(baseModule)/account/login-protocol/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2e82739b8e3d7b200bf8b47aaab7a4f8c24a7e4c --- /dev/null +++ b/employee-portal/src/app/(baseModule)/account/login-protocol/page.tsx @@ -0,0 +1,202 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiUserEvent, ApiUserEventType } from "@eshg/employee-portal-api/base"; +import { formatDateTime } from "@eshg/lib-portal/formatters/dateTime"; +import ChevronLeft from "@mui/icons-material/ChevronLeft"; +import ChevronRight from "@mui/icons-material/ChevronRight"; +import SkipPrevious from "@mui/icons-material/SkipPrevious"; +import { Chip, Stack, Typography } from "@mui/joy"; +import { createColumnHelper } from "@tanstack/react-table"; +import { useState } from "react"; +import { isNonNullish } from "remeda"; + +import { useGetSelfUserEvents } from "@/lib/baseModule/api/queries/users"; +import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; +import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; +import { Toolbar } from "@/lib/shared/components/layout/Toolbar"; +import { IconButton } from "@/lib/shared/components/pagination/IconButton"; +import { RowsPerPageSelect } from "@/lib/shared/components/pagination/RowsPerPageSelect"; +import { + defaultPageSizeOptions, + getPageSizeOptions, +} from "@/lib/shared/components/pagination/paginationHelper"; +import { DataTable } from "@/lib/shared/components/table/DataTable"; +import { TablePage } from "@/lib/shared/components/table/TablePage"; +import { TableSheet } from "@/lib/shared/components/table/TableSheet"; + +const columnHelper = createColumnHelper<ApiUserEvent>(); +const columns = [ + columnHelper.accessor("timestamp", { + header: "Zeitstempel", + enableSorting: false, + cell: (props) => formatDateTime(props.getValue()), + meta: { + width: "15rem", + }, + }), + columnHelper.accessor("type", { + header: "Typ", + enableSorting: false, + cell: (props) => + props.getValue() === ApiUserEventType.Login ? ( + <Chip color={"success"}>Login</Chip> + ) : ( + <Chip color={"danger"}>Login fehlgeschlagen</Chip> + ), + meta: { + width: "15rem", + }, + }), + columnHelper.accessor("ipAddress", { + header: "IP-Adresse", + enableSorting: false, + cell: (props) => props.getValue(), + }), +]; + +export default function UserLoginProtocolPage() { + const [paginationProps, setPaginationProps] = useState({ + limit: 25, + offset: 0, + }); + + function onOffsetChange(newOffset: number) { + setPaginationProps((prev) => ({ + ...prev, + offset: newOffset, + })); + } + + function onPageSizeChange(newPageSize: number) { + setPaginationProps({ + limit: newPageSize, + offset: 0, + }); + } + + const { limit, offset } = paginationProps; + + const { data, isFetching } = useGetSelfUserEvents({ + limit: limit, + offset, + }); + + const { elements, hasNext } = data; + + return ( + <StickyToolbarLayout toolbar={<Toolbar title={"Anmeldeprotokoll"} />}> + <MainContentLayout fullViewportHeight> + <TablePage fullHeight data-testid={"login-protocol-table"}> + <TableSheet + loading={isFetching} + footer={ + <OffsetPagination + hasNextPage={hasNext} + offset={offset} + pageSize={limit} + numberOfElements={elements.length} + onOffsetChange={onOffsetChange} + onPageSizeChange={onPageSizeChange} + pageSizeOptions={defaultPageSizeOptions} + /> + } + > + <DataTable data={elements} columns={columns} minWidth={"40rem"} /> + </TableSheet> + </TablePage> + </MainContentLayout> + </StickyToolbarLayout> + ); +} + +interface OffsetPaginationProps { + hasNextPage: boolean; + offset: number; + pageSize: number; + numberOfElements: number; + onOffsetChange: (newPageNumber: number) => void; + onPageSizeChange: (newPageSize: number) => void; + pageSizeOptions: number[]; +} + +function OffsetPagination(props: OffsetPaginationProps) { + const isFirstPage = props.offset < 1; + const isLastPage = !props.hasNextPage; + + function goToFirstPage() { + props.onOffsetChange(0); + } + + function goToPreviousPage() { + props.onOffsetChange(Math.max(0, props.offset - props.pageSize)); + } + + function goToNextPage() { + props.onOffsetChange(props.offset + props.pageSize); + } + + return ( + <> + <Stack mt={3} direction="row" gap={2} justifyContent={"space-between"}> + <RowsPerPageSelect + value={`${props.pageSize}`} + onChange={(_event, newValue) => { + if (isNonNullish(newValue)) + props.onPageSizeChange(Number(newValue)); + }} + options={getPageSizeOptions( + props.pageSizeOptions, + " Zeilen pro Seite", + )} + sx={{ + width: "13rem", + display: { + xxs: "none", + md: "flex", + }, + }} + /> + + <Stack + direction={"row"} + gap={{ xxs: 1, md: 3 }} + justifyContent={{ xxs: "space-between", md: "flex-end" }} + alignItems={"center"} + flex={1} + > + <Stack direction={"row"} gap={1}> + <IconButton + label={"Zur ersten Seite"} + disabled={isFirstPage} + onClick={goToFirstPage} + > + <SkipPrevious /> + </IconButton> + <IconButton + label={"Zur vorherigen Seite"} + disabled={isFirstPage} + onClick={goToPreviousPage} + > + <ChevronLeft /> + </IconButton> + </Stack> + <Typography level={"body-sm"} textColor={"text.secondary"}> + {props.offset + 1} - {props.offset + props.numberOfElements} + </Typography> + <IconButton + label={"Zur nächsten Seite"} + disabled={isLastPage} + onClick={goToNextPage} + > + <ChevronRight /> + </IconButton> + </Stack> + </Stack> + </> + ); +} diff --git a/employee-portal/src/app/(baseModule)/auditlog/authorize/page.tsx b/employee-portal/src/app/(baseModule)/auditlog/authorize/page.tsx index cdc150e905e16a326b967e4b0be29945c273a98c..cd8c7c6c996ee8b8a6c5251b046ebd292e32ff91 100644 --- a/employee-portal/src/app/(baseModule)/auditlog/authorize/page.tsx +++ b/employee-portal/src/app/(baseModule)/auditlog/authorize/page.tsx @@ -8,8 +8,8 @@ import { ApiUserRole } from "@eshg/employee-portal-api/base"; import { useParams, useRouter } from "next/navigation"; -import { AuditLogAuthorizePage } from "@/lib/baseModule/components/auditlog/authorize/AuditLogAuthorizePage"; -import { AuditLogAuthorizeSidebar } from "@/lib/baseModule/components/auditlog/authorize/AuditLogAuthorizeSidebar"; +import { AuditLogAuthorizePage } from "@/lib/auditlog/components/authorize/AuditLogAuthorizePage"; +import { AuditLogAuthorizeSidebar } from "@/lib/auditlog/components/authorize/AuditLogAuthorizeSidebar"; import { routes } from "@/lib/baseModule/shared/routes"; import { RestrictedPage } from "@/lib/shared/components/RestrictedPage"; import { OverlayBoundary } from "@/lib/shared/components/boundaries/OverlayBoundary"; diff --git a/employee-portal/src/app/(baseModule)/auditlog/page.tsx b/employee-portal/src/app/(baseModule)/auditlog/page.tsx index 4815f085094f84bf4a694e6b343f31bcff6981ec..f0b1521d549dd333c2119273a50e8ee1f7bb3d2b 100644 --- a/employee-portal/src/app/(baseModule)/auditlog/page.tsx +++ b/employee-portal/src/app/(baseModule)/auditlog/page.tsx @@ -5,13 +5,16 @@ "use client"; +import { ApiAuditLogFeature } from "@eshg/employee-portal-api/auditlog"; import { ApiUserRole } from "@eshg/employee-portal-api/base"; import { PortalError } from "@eshg/lib-portal/errorHandling/PortalError"; import { PortalErrorCode } from "@eshg/lib-portal/errorHandling/PortalErrorCode"; +import { AuditlogAccessibleTableView } from "@/lib/auditlog/components/AuditlogAccessibleTableView"; +import { AuditlogCreatePasswordView } from "@/lib/auditlog/components/AuditlogCreatePasswordView"; +import { AuditlogRecordingView } from "@/lib/auditlog/components/AuditlogRecordingView"; +import { useIsNewFeatureEnabled } from "@/lib/auditlog/queries/featureToggles"; import { useGetEmployeePrivateUserKey } from "@/lib/baseModule/api/queries/users"; -import { AuditlogCreatePasswordView } from "@/lib/baseModule/components/auditlog/AuditlogCreatePasswordView"; -import { AuditlogRecordingView } from "@/lib/baseModule/components/auditlog/AuditlogRecordingView"; import { RestrictedPage } from "@/lib/shared/components/RestrictedPage"; import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; @@ -31,6 +34,9 @@ export default function AuditlogPage() { function AuditlogView() { const { data: response } = useGetEmployeePrivateUserKey(); + const isAuditlogAccessibleTableEnabled = useIsNewFeatureEnabled( + ApiAuditLogFeature.AuditLogAccessibleTable, + ); function isPortalErrorNotFound() { return ( @@ -43,5 +49,9 @@ function AuditlogView() { return <AuditlogCreatePasswordView />; } - return <AuditlogRecordingView />; + if (isAuditlogAccessibleTableEnabled) { + return <AuditlogAccessibleTableView />; + } else { + return <AuditlogRecordingView />; + } } diff --git a/employee-portal/src/app/(baseModule)/metrics/[businessModuleName]/[procedureType]/page.tsx b/employee-portal/src/app/(baseModule)/metrics/[businessModuleName]/[procedureType]/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..dc99827b43aa0c676dcfb2b218747f7cf9ef9be9 --- /dev/null +++ b/employee-portal/src/app/(baseModule)/metrics/[businessModuleName]/[procedureType]/page.tsx @@ -0,0 +1,54 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiProcedureType } from "@eshg/employee-portal-api/base"; +import { endOfToday } from "date-fns"; +import { useState } from "react"; + +import { useTaskMetricsQuery } from "@/lib/baseModule/api/queries/taskMetrics"; +import { lastXMonthsInDate } from "@/lib/baseModule/components/procedureMetrics/rangeSelectHelper"; +import { routes } from "@/lib/baseModule/shared/routes"; +import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; +import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; +import { Toolbar } from "@/lib/shared/components/layout/Toolbar"; + +export default function TaskMetricsPage( + props: Readonly<{ + params: { + businessModuleName: string; + procedureType: ApiProcedureType; + }; + }>, +) { + const timeRangeEnd = endOfToday(); + + const [selectedTimeRange, _setSelectedTimeRange] = useState(12); + + const timeRangeStart = lastXMonthsInDate(timeRangeEnd, selectedTimeRange); + + const procedureMetrics = useTaskMetricsQuery({ + businessModuleName: props.params.businessModuleName, + procedureType: props.params.procedureType, + timeRangeStart, + timeRangeEnd, + }); + + return ( + <StickyToolbarLayout + toolbar={ + <Toolbar + title={`Aufgabenkennzahlen: ${props.params.procedureType}`} + backHref={routes.metrics.index} + /> + } + > + <MainContentLayout> + {procedureMetrics.taskMetrics.join()} + </MainContentLayout> + </StickyToolbarLayout> + ); +} diff --git a/employee-portal/src/app/(baseModule)/metrics/page.tsx b/employee-portal/src/app/(baseModule)/metrics/page.tsx index 67e564268c13918505176a8ab5a7f2723bc02670..85b993b197ab0199bf8655dc4bb876c1f76e305b 100644 --- a/employee-portal/src/app/(baseModule)/metrics/page.tsx +++ b/employee-portal/src/app/(baseModule)/metrics/page.tsx @@ -5,38 +5,16 @@ "use client"; -import { endOfToday } from "date-fns"; -import { startTransition, useState } from "react"; - -import { useAggregateProcedureMetricsQuery } from "@/lib/baseModule/api/queries/procedures"; import { ProcedureMetricsDisplay } from "@/lib/baseModule/components/procedureMetrics/ProcedureMetricsDisplay"; -import { lastXMonthsInDate } from "@/lib/baseModule/components/procedureMetrics/rangeSelectHelper"; import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; import { Toolbar } from "@/lib/shared/components/layout/Toolbar"; export default function ProcedureMetricsPage() { - const today = endOfToday(); - - const [selectedTimeRange, setSelectedTimeRange] = useState(12); - - const { data: procedureMetrics } = useAggregateProcedureMetricsQuery({ - timeRangeStart: lastXMonthsInDate(today, selectedTimeRange), - timeRangeEnd: today, - }); - return ( <StickyToolbarLayout toolbar={<Toolbar title={"Kennzahlen"} />}> <MainContentLayout> - <ProcedureMetricsDisplay - procedureMetrics={procedureMetrics} - setSelectedTimeRange={(range) => { - startTransition(() => { - setSelectedTimeRange(range); - }); - }} - selectedTimeRange={selectedTimeRange} - /> + <ProcedureMetricsDisplay /> </MainContentLayout> </StickyToolbarLayout> ); diff --git a/employee-portal/src/app/(baseModule)/usage-notes/page.tsx b/employee-portal/src/app/(baseModule)/usage-notes/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d38e1568ce22e1f2e11d13e8e3951beec8c86f0f --- /dev/null +++ b/employee-portal/src/app/(baseModule)/usage-notes/page.tsx @@ -0,0 +1,27 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { UsageNotes } from "@/lib/baseModule/components/usage/UsageNotes"; +import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; +import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; +import { Toolbar } from "@/lib/shared/components/layout/Toolbar"; + +export default function UsageNotesPage() { + return ( + <StickyToolbarLayout + toolbar={ + <Toolbar + title={ + "Nutzungshinweise für die sichere Benutzung des Mitarbeitenden-Portals" + } + /> + } + > + <MainContentLayout> + <UsageNotes /> + </MainContentLayout> + </StickyToolbarLayout> + ); +} diff --git a/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/inspection/page.tsx b/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/inspection/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..605897b214b08d9f846af3bd2eb3bee246092c5e --- /dev/null +++ b/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/inspection/page.tsx @@ -0,0 +1,29 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiBusinessModule } from "@eshg/employee-portal-api/businessProcedures"; + +import { + useBulkUpdateProceduresArchivingRelevance, + useExportRelevantProcedures, +} from "@/lib/businessModules/inspection/api/mutations/archiving"; +import { useGetRelevantArchivableProcedures } from "@/lib/businessModules/inspection/api/queries/archiving"; +import { ArchiveAdminView } from "@/lib/shared/components/archiving/ArchiveAdminView"; +import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; + +export default function ArchiveAdminPage() { + return ( + <ArchiveAdminView + title={businessModuleNames[ApiBusinessModule.Inspection]} + useGetRelevantArchivableProcedures={useGetRelevantArchivableProcedures} + useExportRelevantProcedures={useExportRelevantProcedures} + useBulkUpdateProceduresArchivingRelevance={ + useBulkUpdateProceduresArchivingRelevance + } + /> + ); +} diff --git a/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/measles-protection/page.tsx b/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/measles-protection/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..cd71de02ed4b2c8dbb8b45b9dd1493f78c1c68bd --- /dev/null +++ b/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/measles-protection/page.tsx @@ -0,0 +1,29 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiBusinessModule } from "@eshg/employee-portal-api/businessProcedures"; + +import { + useBulkUpdateProceduresArchivingRelevance, + useExportRelevantProcedures, +} from "@/lib/businessModules/measlesProtection/api/mutations/archiving"; +import { useGetRelevantArchivableProcedures } from "@/lib/businessModules/measlesProtection/api/queries/archiving"; +import { ArchiveAdminView } from "@/lib/shared/components/archiving/ArchiveAdminView"; +import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; + +export default function ArchiveAdminPage() { + return ( + <ArchiveAdminView + title={businessModuleNames[ApiBusinessModule.MeaslesProtection]} + useGetRelevantArchivableProcedures={useGetRelevantArchivableProcedures} + useExportRelevantProcedures={useExportRelevantProcedures} + useBulkUpdateProceduresArchivingRelevance={ + useBulkUpdateProceduresArchivingRelevance + } + /> + ); +} diff --git a/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/school-entry/page.tsx b/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/school-entry/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a4cd723e68d7ab5b4716744352607f579251d44e --- /dev/null +++ b/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/school-entry/page.tsx @@ -0,0 +1,29 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiBusinessModule } from "@eshg/employee-portal-api/businessProcedures"; + +import { + useBulkUpdateProceduresArchivingRelevance, + useExportRelevantProcedures, +} from "@/lib/businessModules/schoolEntry/api/mutations/archiving"; +import { useGetRelevantArchivableProcedures } from "@/lib/businessModules/schoolEntry/api/queries/archiving"; +import { ArchiveAdminView } from "@/lib/shared/components/archiving/ArchiveAdminView"; +import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; + +export default function ArchiveAdminPage() { + return ( + <ArchiveAdminView + title={businessModuleNames[ApiBusinessModule.SchoolEntry]} + useGetRelevantArchivableProcedures={useGetRelevantArchivableProcedures} + useExportRelevantProcedures={useExportRelevantProcedures} + useBulkUpdateProceduresArchivingRelevance={ + useBulkUpdateProceduresArchivingRelevance + } + /> + ); +} diff --git a/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/sti-protection/page.tsx b/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/sti-protection/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c08d37f1dc656e797c6712faa6fb7c97244a5bed --- /dev/null +++ b/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/sti-protection/page.tsx @@ -0,0 +1,29 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiBusinessModule } from "@eshg/employee-portal-api/businessProcedures"; + +import { + useBulkUpdateProceduresArchivingRelevance, + useExportRelevantProcedures, +} from "@/lib/businessModules/stiProtection/api/mutations/archiving"; +import { useGetRelevantArchivableProcedures } from "@/lib/businessModules/stiProtection/api/queries/archiving"; +import { ArchiveAdminView } from "@/lib/shared/components/archiving/ArchiveAdminView"; +import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; + +export default function ArchiveAdminPage() { + return ( + <ArchiveAdminView + title={businessModuleNames[ApiBusinessModule.StiProtection]} + useGetRelevantArchivableProcedures={useGetRelevantArchivableProcedures} + useExportRelevantProcedures={useExportRelevantProcedures} + useBulkUpdateProceduresArchivingRelevance={ + useBulkUpdateProceduresArchivingRelevance + } + /> + ); +} diff --git a/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/travel-medicine/page.tsx b/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/travel-medicine/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..386718f098ff5b92761c0c3134b68982985fb7b4 --- /dev/null +++ b/employee-portal/src/app/(businessModules)/(archiving)/archiving-admin/travel-medicine/page.tsx @@ -0,0 +1,29 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiBusinessModule } from "@eshg/employee-portal-api/businessProcedures"; + +import { + useBulkUpdateProceduresArchivingRelevance, + useExportRelevantProcedures, +} from "@/lib/businessModules/travelMedicine/api/mutations/archiving"; +import { useGetRelevantArchivableProcedures } from "@/lib/businessModules/travelMedicine/api/queries/archiving"; +import { ArchiveAdminView } from "@/lib/shared/components/archiving/ArchiveAdminView"; +import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; + +export default function ArchiveAdminPage() { + return ( + <ArchiveAdminView + title={businessModuleNames[ApiBusinessModule.TravelMedicine]} + useGetRelevantArchivableProcedures={useGetRelevantArchivableProcedures} + useExportRelevantProcedures={useExportRelevantProcedures} + useBulkUpdateProceduresArchivingRelevance={ + useBulkUpdateProceduresArchivingRelevance + } + /> + ); +} diff --git a/employee-portal/src/app/(businessModules)/(archiving)/archiving/inspection/page.tsx b/employee-portal/src/app/(businessModules)/(archiving)/archiving/inspection/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b6dcca733b28becf93b45f22e37f19b7a6c7d87a --- /dev/null +++ b/employee-portal/src/app/(businessModules)/(archiving)/archiving/inspection/page.tsx @@ -0,0 +1,33 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiBusinessModule } from "@eshg/employee-portal-api/businessProcedures"; + +import { useBulkUpdateProceduresArchivingRelevance } from "@/lib/businessModules/inspection/api/mutations/archiving"; +import { + useGetArchivableProcedures, + useGetArchivingConfiguration, +} from "@/lib/businessModules/inspection/api/queries/archiving"; +import { procedureTypes } from "@/lib/businessModules/inspection/shared/constants"; +import { routes } from "@/lib/businessModules/inspection/shared/routes"; +import { ArchiveView } from "@/lib/shared/components/archiving/ArchiveView"; +import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; + +export default function ArchivePage() { + return ( + <ArchiveView + title={businessModuleNames[ApiBusinessModule.Inspection]} + procedureDetailsRoute={routes.procedures.details} + useGetArchivingConfiguration={useGetArchivingConfiguration} + useGetArchivableProcedures={useGetArchivableProcedures} + useBulkUpdateProceduresArchivingRelevance={ + useBulkUpdateProceduresArchivingRelevance + } + additionalFilters={{ procedureTypes }} + /> + ); +} diff --git a/employee-portal/src/app/(businessModules)/(archiving)/archiving/measles-protection/page.tsx b/employee-portal/src/app/(businessModules)/(archiving)/archiving/measles-protection/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e6e59f1963f996474f521bc8e75224f4d7752147 --- /dev/null +++ b/employee-portal/src/app/(businessModules)/(archiving)/archiving/measles-protection/page.tsx @@ -0,0 +1,35 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiBusinessModule } from "@eshg/employee-portal-api/businessProcedures"; + +import { useBulkUpdateProceduresArchivingRelevance } from "@/lib/businessModules/measlesProtection/api/mutations/archiving"; +import { + useGetArchivableProcedures, + useGetArchivingConfiguration, +} from "@/lib/businessModules/measlesProtection/api/queries/archiving"; +import { procedureTypes } from "@/lib/businessModules/measlesProtection/shared/constants"; +import { routes } from "@/lib/businessModules/measlesProtection/shared/routes"; +import { ArchiveView } from "@/lib/shared/components/archiving/ArchiveView"; +import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; + +export default function ArchivePage() { + return ( + <ArchiveView + title={businessModuleNames[ApiBusinessModule.MeaslesProtection]} + procedureDetailsRoute={(procedureId: string) => + routes.procedures.details(procedureId).index + } + useGetArchivingConfiguration={useGetArchivingConfiguration} + useGetArchivableProcedures={useGetArchivableProcedures} + useBulkUpdateProceduresArchivingRelevance={ + useBulkUpdateProceduresArchivingRelevance + } + additionalFilters={{ procedureTypes }} + /> + ); +} diff --git a/employee-portal/src/app/(businessModules)/(archiving)/archiving/school-entry/page.tsx b/employee-portal/src/app/(businessModules)/(archiving)/archiving/school-entry/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..36f3c32cbeda292ae43a5c7a4968dabcf1f2b8d1 --- /dev/null +++ b/employee-portal/src/app/(businessModules)/(archiving)/archiving/school-entry/page.tsx @@ -0,0 +1,35 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiBusinessModule } from "@eshg/employee-portal-api/businessProcedures"; + +import { useBulkUpdateProceduresArchivingRelevance } from "@/lib/businessModules/schoolEntry/api/mutations/archiving"; +import { + useGetArchivableProcedures, + useGetArchivingConfiguration, +} from "@/lib/businessModules/schoolEntry/api/queries/archiving"; +import { procedureTypes } from "@/lib/businessModules/schoolEntry/shared/constants"; +import { routes } from "@/lib/businessModules/schoolEntry/shared/routes"; +import { ArchiveView } from "@/lib/shared/components/archiving/ArchiveView"; +import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; + +export default function ArchivePage() { + return ( + <ArchiveView + title={businessModuleNames[ApiBusinessModule.SchoolEntry]} + procedureDetailsRoute={(procedureId: string) => + routes.procedures.byId(procedureId).details + } + useGetArchivingConfiguration={useGetArchivingConfiguration} + useGetArchivableProcedures={useGetArchivableProcedures} + useBulkUpdateProceduresArchivingRelevance={ + useBulkUpdateProceduresArchivingRelevance + } + additionalFilters={{ procedureTypes }} + /> + ); +} diff --git a/employee-portal/src/app/(businessModules)/(archiving)/archiving/sti-protection/page.tsx b/employee-portal/src/app/(businessModules)/(archiving)/archiving/sti-protection/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..fb9d113b40cdb2cc6be43fa67a99c44b08ad42cd --- /dev/null +++ b/employee-portal/src/app/(businessModules)/(archiving)/archiving/sti-protection/page.tsx @@ -0,0 +1,35 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiBusinessModule } from "@eshg/employee-portal-api/businessProcedures"; + +import { useBulkUpdateProceduresArchivingRelevance } from "@/lib/businessModules/stiProtection/api/mutations/archiving"; +import { + useGetArchivableProcedures, + useGetArchivingConfiguration, +} from "@/lib/businessModules/stiProtection/api/queries/archiving"; +import { procedureTypes } from "@/lib/businessModules/stiProtection/shared/constants"; +import { routes } from "@/lib/businessModules/stiProtection/shared/routes"; +import { ArchiveView } from "@/lib/shared/components/archiving/ArchiveView"; +import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; + +export default function ArchivePage() { + return ( + <ArchiveView + title={businessModuleNames[ApiBusinessModule.StiProtection]} + procedureDetailsRoute={(procedureId: string) => + routes.procedures.byId(procedureId).details + } + useGetArchivingConfiguration={useGetArchivingConfiguration} + useGetArchivableProcedures={useGetArchivableProcedures} + useBulkUpdateProceduresArchivingRelevance={ + useBulkUpdateProceduresArchivingRelevance + } + additionalFilters={{ procedureTypes }} + /> + ); +} diff --git a/employee-portal/src/app/(businessModules)/(archiving)/archiving/travel-medicine/page.tsx b/employee-portal/src/app/(businessModules)/(archiving)/archiving/travel-medicine/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..93d464cafade7eaa0d5f1e714b5a6e300fe54e20 --- /dev/null +++ b/employee-portal/src/app/(businessModules)/(archiving)/archiving/travel-medicine/page.tsx @@ -0,0 +1,33 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiBusinessModule } from "@eshg/employee-portal-api/businessProcedures"; + +import { useBulkUpdateProceduresArchivingRelevance } from "@/lib/businessModules/travelMedicine/api/mutations/archiving"; +import { + useGetArchivableProcedures, + useGetArchivingConfiguration, +} from "@/lib/businessModules/travelMedicine/api/queries/archiving"; +import { procedureTypes } from "@/lib/businessModules/travelMedicine/shared/constants"; +import { routes } from "@/lib/businessModules/travelMedicine/shared/routes"; +import { ArchiveView } from "@/lib/shared/components/archiving/ArchiveView"; +import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; + +export default function ArchivePage() { + return ( + <ArchiveView + title={businessModuleNames[ApiBusinessModule.TravelMedicine]} + procedureDetailsRoute={routes.procedures.baseData} + useGetArchivingConfiguration={useGetArchivingConfiguration} + useGetArchivableProcedures={useGetArchivableProcedures} + useBulkUpdateProceduresArchivingRelevance={ + useBulkUpdateProceduresArchivingRelevance + } + additionalFilters={{ procedureTypes }} + /> + ); +} diff --git a/employee-portal/src/app/(businessModules)/inspection/checklist/def/page.tsx b/employee-portal/src/app/(businessModules)/inspection/checklist/def/page.tsx index 42949972b5883c367091d043edbdc50bf9a28b80..5184b6678c810d55c7bbb4990144941a726c8a13 100644 --- a/employee-portal/src/app/(businessModules)/inspection/checklist/def/page.tsx +++ b/employee-portal/src/app/(businessModules)/inspection/checklist/def/page.tsx @@ -10,7 +10,7 @@ import { InternalLinkButton } from "@eshg/lib-portal/components/navigation/Inter import AddIcon from "@mui/icons-material/Add"; import { Box } from "@mui/joy"; -import { ChecklistDefinitionOverviewTable } from "@/lib/businessModules/inspection/components/checklistDefinition/ChecklistDefinitionOverviewTable"; +import { ChecklistDefinitionOverviewTable } from "@/lib/businessModules/inspection/components/checklistDefinition/overview/ChecklistDefinitionOverviewTable"; import { routes } from "@/lib/businessModules/inspection/shared/routes"; import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; diff --git a/employee-portal/src/app/(businessModules)/inspection/teamview/page.tsx b/employee-portal/src/app/(businessModules)/inspection/teamview/page.tsx index 71fdcc2b29bd23b53090e565cb4f741699736907..a64065c9b7af08f1407a9f1b35f464fce4c0f754 100644 --- a/employee-portal/src/app/(businessModules)/inspection/teamview/page.tsx +++ b/employee-portal/src/app/(businessModules)/inspection/teamview/page.tsx @@ -8,7 +8,7 @@ import { ApiBusinessModule, ApiUserRole } from "@eshg/employee-portal-api/base"; import { Teamview } from "@/lib/baseModule/components/task/Teamview"; -import { useFetchTasksForTeamView } from "@/lib/businessModules/inspection/api/queries/useFetchTasksForTeamView"; +import { useFetchTasksForTeamViewOptions } from "@/lib/businessModules/inspection/api/queries/useFetchTasksForTeamViewOptions"; import { moduleUserGroup } from "@/lib/businessModules/inspection/shared/moduleUserGroup"; import { RestrictedPage } from "@/lib/shared/components/RestrictedPage"; import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; @@ -23,7 +23,7 @@ export default function InspectionTeamviewPage() { <Teamview groupName={moduleUserGroup.group} businessModule={ApiBusinessModule.Inspection} - useFetchTasksForTeamView={useFetchTasksForTeamView} + useFetchTasksForTeamViewOptions={useFetchTasksForTeamViewOptions} /> </RestrictedPage> </MainContentLayout> diff --git a/employee-portal/src/app/(businessModules)/measles-protection/appointment-block-groups/new/page.tsx b/employee-portal/src/app/(businessModules)/measles-protection/appointment-block-groups/new/page.tsx index 60e62017df6b1df5eaff2a1cee804a8af9afbba2..d3f87239dd44d7937a78b56f74230e7be8d3595b 100644 --- a/employee-portal/src/app/(businessModules)/measles-protection/appointment-block-groups/new/page.tsx +++ b/employee-portal/src/app/(businessModules)/measles-protection/appointment-block-groups/new/page.tsx @@ -13,7 +13,7 @@ import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolba import { Toolbar } from "@/lib/shared/components/layout/Toolbar"; export default function NewAppointmentBlockGroupsPage() { - const appointmentDurationsMeasles = useGetAppointmentDurations().data; + const { data: appointmentDurationsMeasles } = useGetAppointmentDurations(); return ( <StickyToolbarLayout diff --git a/employee-portal/src/app/(businessModules)/measles-protection/procedures/[id]/@tabs/proof/page.tsx b/employee-portal/src/app/(businessModules)/measles-protection/procedures/[id]/@tabs/proof/page.tsx index a5b350d669d5c88670f8e1009c696f212d667efa..575db0e89ab357e43ea07f27844d03d4a00a331c 100644 --- a/employee-portal/src/app/(businessModules)/measles-protection/procedures/[id]/@tabs/proof/page.tsx +++ b/employee-portal/src/app/(businessModules)/measles-protection/procedures/[id]/@tabs/proof/page.tsx @@ -13,7 +13,7 @@ export default function MeaslesProtectionProcedureDataProofTab({ }>) { return ( <ProceduresProvider> - <ProofTab id={params.id} /> + <ProofTab procedureId={params.id} /> </ProceduresProvider> ); } diff --git a/employee-portal/src/app/(businessModules)/school-entry/procedures/[id]/details/page.tsx b/employee-portal/src/app/(businessModules)/school-entry/procedures/[id]/details/page.tsx index 6dd41c358337b192adb7cbaf0ab9c38b97b8649e..2f9dc2ad00f789e7feac856dc7cdc48385eaad93 100644 --- a/employee-portal/src/app/(businessModules)/school-entry/procedures/[id]/details/page.tsx +++ b/employee-portal/src/app/(businessModules)/school-entry/procedures/[id]/details/page.tsx @@ -5,14 +5,34 @@ "use client"; +import { useSuspenseQueries } from "@tanstack/react-query"; + import { SchoolEntryProcedurePageProps } from "@/app/(businessModules)/school-entry/procedures/[id]/layout"; -import { useGetProcedure } from "@/lib/businessModules/schoolEntry/api/queries/schoolEntryApi"; +import { + useConfigApi, + useSchoolEntryApi, +} from "@/lib/businessModules/schoolEntry/api/clients"; +import { getLocationSelectionModeQuery } from "@/lib/businessModules/schoolEntry/api/queries/configApi"; +import { getProcedureQuery } from "@/lib/businessModules/schoolEntry/api/queries/schoolEntryApi"; import { ProcedureDetails } from "@/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ProcedureDetails"; export default function SchoolEntryProcedureDetailsPage( props: SchoolEntryProcedurePageProps, ) { - const procedureQuery = useGetProcedure(props.params.id); + const schoolEntryApi = useSchoolEntryApi(); + const configApi = useConfigApi(); + const [{ data: procedure }, { data: locationSelectionMode }] = + useSuspenseQueries({ + queries: [ + getProcedureQuery(schoolEntryApi, props.params.id), + getLocationSelectionModeQuery(configApi), + ], + }); - return <ProcedureDetails procedure={procedureQuery.data} />; + return ( + <ProcedureDetails + procedure={procedure} + locationSelectionMode={locationSelectionMode} + /> + ); } diff --git a/employee-portal/src/app/(businessModules)/school-entry/waiting-room/page.tsx b/employee-portal/src/app/(businessModules)/school-entry/waiting-room/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d86b1aa4cef7a54bca3db2eb22082788c5923fc3 --- /dev/null +++ b/employee-portal/src/app/(businessModules)/school-entry/waiting-room/page.tsx @@ -0,0 +1,21 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { WaitingRoomTable } from "@/lib/businessModules/schoolEntry/features/waitingRoom/WaitingRoomTable"; +import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; +import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; +import { Toolbar } from "@/lib/shared/components/layout/Toolbar"; + +export default function SchoolEntryWaitingRoomPage() { + return ( + <StickyToolbarLayout toolbar={<Toolbar title="Wartezimmer" />}> + <MainContentLayout fullViewportHeight> + <WaitingRoomTable /> + </MainContentLayout> + </StickyToolbarLayout> + ); +} diff --git a/employee-portal/src/app/(businessModules)/sti-protection/appointment-block-groups/new/page.tsx b/employee-portal/src/app/(businessModules)/sti-protection/appointment-block-groups/new/page.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c920fd1c812f9c63ed0ba78dfa036ea22fba13f4 --- /dev/null +++ b/employee-portal/src/app/(businessModules)/sti-protection/appointment-block-groups/new/page.tsx @@ -0,0 +1,29 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { CreateAppointmentBlockGroupForm } from "@/lib/businessModules/stiProtection/components/appointmentBlocks/CreateAppointmentBlockGroupForm"; +import { routes } from "@/lib/businessModules/stiProtection/shared/routes"; +import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; +import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; +import { Toolbar } from "@/lib/shared/components/layout/Toolbar"; + +export default function NewAppointmentBlockGroupsPage() { + return ( + <StickyToolbarLayout + toolbar={ + <Toolbar + title="Neuen Terminblock planen" + backHref={routes.appointmentBlockGroups.index} + /> + } + > + <MainContentLayout> + <CreateAppointmentBlockGroupForm /> + </MainContentLayout> + </StickyToolbarLayout> + ); +} diff --git a/employee-portal/src/app/(businessModules)/sti-protection/appointment-block-groups/page.tsx b/employee-portal/src/app/(businessModules)/sti-protection/appointment-block-groups/page.tsx index 74c7396d04cae68fa3ffe05d010b77dd876b7605..db890d7bf4d2a41e98c0458bd0c6da97ebb22e61 100644 --- a/employee-portal/src/app/(businessModules)/sti-protection/appointment-block-groups/page.tsx +++ b/employee-portal/src/app/(businessModules)/sti-protection/appointment-block-groups/page.tsx @@ -25,7 +25,6 @@ export default function AppointmentBlockGroupsOverviewPage() { href={routes.appointmentBlockGroups.new} size="sm" startDecorator={<Schedule />} - disabled > Terminblock planen </InternalLinkButton> diff --git a/employee-portal/src/app/(baseModule)/imprint/page.tsx b/employee-portal/src/app/(businessModules)/sti-protection/appointment-definition/page.tsx similarity index 58% rename from employee-portal/src/app/(baseModule)/imprint/page.tsx rename to employee-portal/src/app/(businessModules)/sti-protection/appointment-definition/page.tsx index 3ce001b79d149c06152809e4823a2d3cbbafc98c..4a5219467a218f75492776960ae2a8a8b2c425b5 100644 --- a/employee-portal/src/app/(baseModule)/imprint/page.tsx +++ b/employee-portal/src/app/(businessModules)/sti-protection/appointment-definition/page.tsx @@ -3,16 +3,16 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { Imprint } from "@/lib/baseModule/components/imprint/Imprint"; +import { AppointmentTypeOverviewTable } from "@/lib/businessModules/stiProtection/components/appointmentTypes/AppointmentTypeOverviewTable"; import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; import { Toolbar } from "@/lib/shared/components/layout/Toolbar"; -export default function ImprintPage() { +export default function AppointmentTypeOverviewPage() { return ( - <StickyToolbarLayout toolbar={<Toolbar title={"Impressum"} />}> + <StickyToolbarLayout toolbar={<Toolbar title="Terminarten" />}> <MainContentLayout> - <Imprint /> + <AppointmentTypeOverviewTable /> </MainContentLayout> </StickyToolbarLayout> ); diff --git a/employee-portal/src/lib/auditlog/api/clients.ts b/employee-portal/src/lib/auditlog/api/clients.ts index ee43affd1f0dcf1ec4c4fdfddfc20bd67cdd5b5b..317b10a496abecd364b51b1bb8b291fc692e827e 100644 --- a/employee-portal/src/lib/auditlog/api/clients.ts +++ b/employee-portal/src/lib/auditlog/api/clients.ts @@ -3,7 +3,11 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { AuditLogApi, Configuration } from "@eshg/employee-portal-api/auditlog"; +import { + AuditLogApi, + AuditLogFeatureTogglesApi, + Configuration, +} from "@eshg/employee-portal-api/auditlog"; import { useApiConfiguration } from "@eshg/lib-portal/api/ApiProvider"; function useConfiguration() { @@ -14,6 +18,9 @@ function useConfiguration() { } export function useAuditlogApi() { - const configuration = useConfiguration(); - return new AuditLogApi(configuration); + return new AuditLogApi(useConfiguration()); +} + +export function useFeatureTogglesApi() { + return new AuditLogFeatureTogglesApi(useConfiguration()); } diff --git a/employee-portal/src/lib/auditlog/api/models/auditlog.ts b/employee-portal/src/lib/auditlog/api/models/auditlog.ts index c8213f6711012bc75e15fbc8be63f7530a908de4..e3c543aa2c8dbdf340361c40d1849b33f934af59 100644 --- a/employee-portal/src/lib/auditlog/api/models/auditlog.ts +++ b/employee-portal/src/lib/auditlog/api/models/auditlog.ts @@ -4,7 +4,7 @@ */ import { - ApiAuditLogGrantedAccessDto, + ApiAuditLogGrantedAccessCount, ApiAuditLogSource, ApiGetAvailableAuditLogsResponse, } from "@eshg/employee-portal-api/auditlog/models"; @@ -31,7 +31,7 @@ export function mapResponse( }; } -function mapAuditLog(log: ApiAuditLogGrantedAccessDto): AuditLog { +function mapAuditLog(log: ApiAuditLogGrantedAccessCount): AuditLog { return { auditLogSource: log.auditLog.source, createdAt: log.auditLog.date, diff --git a/employee-portal/src/lib/auditlog/components/AuditlogAccessibleTableView.tsx b/employee-portal/src/lib/auditlog/components/AuditlogAccessibleTableView.tsx new file mode 100644 index 0000000000000000000000000000000000000000..6a1adf2c5be6270b94dbe3878386c9ea52ea574e --- /dev/null +++ b/employee-portal/src/lib/auditlog/components/AuditlogAccessibleTableView.tsx @@ -0,0 +1,38 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { AuditlogDeletePasswordButton } from "@/lib/auditlog/components/AuditlogDeletePasswordButton"; +import { auditLogAccessibleColumns } from "@/lib/auditlog/components/auditLogAccessibleColumns"; +import { useGetAccessibleAuditLogs } from "@/lib/auditlog/queries/auditlog"; +import { ButtonBar } from "@/lib/shared/components/buttons/ButtonBar"; +import { FilterButton } from "@/lib/shared/components/buttons/FilterButton"; +import { DataTable } from "@/lib/shared/components/table/DataTable"; +import { TablePage } from "@/lib/shared/components/table/TablePage"; +import { TableSheet } from "@/lib/shared/components/table/TableSheet"; + +export function AuditlogAccessibleTableView() { + const { data: response } = useGetAccessibleAuditLogs(); + + return ( + <TablePage + fullHeight + controls={ + <ButtonBar + left={<FilterButton disabled />} + right={<AuditlogDeletePasswordButton />} + /> + } + > + <TableSheet> + <DataTable + data={response.accessibleAuditLogs} + columns={auditLogAccessibleColumns} + /> + </TableSheet> + </TablePage> + ); +} diff --git a/employee-portal/src/lib/baseModule/components/auditlog/AuditlogCreatePasswordSidebar.tsx b/employee-portal/src/lib/auditlog/components/AuditlogCreatePasswordSidebar.tsx similarity index 98% rename from employee-portal/src/lib/baseModule/components/auditlog/AuditlogCreatePasswordSidebar.tsx rename to employee-portal/src/lib/auditlog/components/AuditlogCreatePasswordSidebar.tsx index 752624c7d5316a437edd4c9c00cf4480d06fbeb5..44707b477c11af7c21b82d72e9a9446f9df131f9 100644 --- a/employee-portal/src/lib/baseModule/components/auditlog/AuditlogCreatePasswordSidebar.tsx +++ b/employee-portal/src/lib/auditlog/components/AuditlogCreatePasswordSidebar.tsx @@ -10,8 +10,8 @@ import { Formik } from "formik"; import { useRouter } from "next/navigation"; import { useRef } from "react"; +import { generateKeyPairs } from "@/lib/auditlog/components/crypto"; import { useAddEmployeeSelfUserKeys } from "@/lib/baseModule/api/mutations/users"; -import { generateKeyPairs } from "@/lib/baseModule/components/auditlog/crypto"; import { routes } from "@/lib/baseModule/shared/routes"; import { FormButtonBar } from "@/lib/shared/components/form/FormButtonBar"; import { diff --git a/employee-portal/src/lib/baseModule/components/auditlog/AuditlogCreatePasswordView.tsx b/employee-portal/src/lib/auditlog/components/AuditlogCreatePasswordView.tsx similarity index 92% rename from employee-portal/src/lib/baseModule/components/auditlog/AuditlogCreatePasswordView.tsx rename to employee-portal/src/lib/auditlog/components/AuditlogCreatePasswordView.tsx index 56541c1ca25053bd08d3d0af87f2ba132308dc6e..a58565ea1482ae9c758f0cc4214d93d3a9bab0fe 100644 --- a/employee-portal/src/lib/baseModule/components/auditlog/AuditlogCreatePasswordView.tsx +++ b/employee-portal/src/lib/auditlog/components/AuditlogCreatePasswordView.tsx @@ -9,7 +9,7 @@ import { CancelOutlined, KeyOutlined } from "@mui/icons-material"; import { Button, Sheet, Stack, Typography } from "@mui/joy"; import { Dispatch, SetStateAction, useState } from "react"; -import { AuditlogCreatePasswordSidebar } from "@/lib/baseModule/components/auditlog/AuditlogCreatePasswordSidebar"; +import { AuditlogCreatePasswordSidebar } from "@/lib/auditlog/components/AuditlogCreatePasswordSidebar"; import { OverlayBoundary } from "@/lib/shared/components/boundaries/OverlayBoundary"; import { ButtonBar } from "@/lib/shared/components/buttons/ButtonBar"; import { FilterButton } from "@/lib/shared/components/buttons/FilterButton"; @@ -20,7 +20,7 @@ export function AuditlogCreatePasswordView() { return ( <> <ButtonBar - left={<FilterButton />} + left={<FilterButton disabled />} right={<CreatePasswordButton setOpen={setOpen} />} /> <Sheet diff --git a/employee-portal/src/lib/baseModule/components/auditlog/AuditlogRecordingView.tsx b/employee-portal/src/lib/auditlog/components/AuditlogDeletePasswordButton.tsx similarity index 53% rename from employee-portal/src/lib/baseModule/components/auditlog/AuditlogRecordingView.tsx rename to employee-portal/src/lib/auditlog/components/AuditlogDeletePasswordButton.tsx index 7414e80ceb4da415074dda35f6790092aed00bb2..5e9f918722c5d71c5caccfe20ee06017fb791103 100644 --- a/employee-portal/src/lib/baseModule/components/auditlog/AuditlogRecordingView.tsx +++ b/employee-portal/src/lib/auditlog/components/AuditlogDeletePasswordButton.tsx @@ -3,42 +3,13 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -"use client"; - -import { GradingTwoTone, KeyOffOutlined } from "@mui/icons-material"; -import { Button, Sheet, Stack, Typography } from "@mui/joy"; +import { KeyOffOutlined } from "@mui/icons-material"; +import { Button } from "@mui/joy"; import { useDeleteEmployeeUserKeys } from "@/lib/baseModule/api/mutations/users"; -import { ButtonBar } from "@/lib/shared/components/buttons/ButtonBar"; -import { FilterButton } from "@/lib/shared/components/buttons/FilterButton"; import { useConfirmationDialog } from "@/lib/shared/components/confirmationDialog/ConfirmationDialogProvider"; -export function AuditlogRecordingView() { - return ( - <> - <ButtonBar left={<FilterButton />} right={<DeletePasswordButton />} /> - <Sheet - data-testid={"auditlogSheet"} - sx={{ - pb: 8, - mt: 2, - display: "flex", - alignItems: "center", - justifyContent: "center", - flex: 1, - border: "none", - }} - > - <Stack alignItems={"center"} gap={2}> - <GradingTwoTone fontSize={"xl4"} /> - <Typography>Audit Logs werden aufgezeichnet</Typography> - </Stack> - </Sheet> - </> - ); -} - -function DeletePasswordButton() { +export function AuditlogDeletePasswordButton() { const { openConfirmationDialog } = useConfirmationDialog(); const deleteEmployeeUserKeys = useDeleteEmployeeUserKeys(); diff --git a/employee-portal/src/lib/auditlog/components/AuditlogRecordingView.tsx b/employee-portal/src/lib/auditlog/components/AuditlogRecordingView.tsx new file mode 100644 index 0000000000000000000000000000000000000000..0e51d969d3a5229232e95a8d8e6b105bb3a1b780 --- /dev/null +++ b/employee-portal/src/lib/auditlog/components/AuditlogRecordingView.tsx @@ -0,0 +1,42 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { GradingTwoTone } from "@mui/icons-material"; +import { Sheet, Stack, Typography } from "@mui/joy"; + +import { ButtonBar } from "@/lib/shared/components/buttons/ButtonBar"; +import { FilterButton } from "@/lib/shared/components/buttons/FilterButton"; + +import { AuditlogDeletePasswordButton } from "./AuditlogDeletePasswordButton"; + +export function AuditlogRecordingView() { + return ( + <> + <ButtonBar + left={<FilterButton disabled />} + right={<AuditlogDeletePasswordButton />} + /> + <Sheet + data-testid={"auditlogSheet"} + sx={{ + pb: 8, + mt: 2, + display: "flex", + alignItems: "center", + justifyContent: "center", + flex: 1, + border: "none", + }} + > + <Stack alignItems={"center"} gap={2}> + <GradingTwoTone fontSize={"xl4"} /> + <Typography>Audit Logs werden aufgezeichnet</Typography> + </Stack> + </Sheet> + </> + ); +} diff --git a/employee-portal/src/lib/auditlog/components/auditLogAccessibleColumns.tsx b/employee-portal/src/lib/auditlog/components/auditLogAccessibleColumns.tsx new file mode 100644 index 0000000000000000000000000000000000000000..3ee7166c8442291d70607bcd46e0860b35251f94 --- /dev/null +++ b/employee-portal/src/lib/auditlog/components/auditLogAccessibleColumns.tsx @@ -0,0 +1,63 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiAccessibleAuditLog } from "@eshg/employee-portal-api/auditlog"; +import { formatDate } from "@eshg/lib-portal/formatters/dateTime"; +import { VisibilityOutlined } from "@mui/icons-material"; +import { Chip, Typography } from "@mui/joy"; +import { createColumnHelper } from "@tanstack/react-table"; + +import { auditLogSourceNames } from "@/lib/shared/components/auditlog/constants"; + +const columnHelper = createColumnHelper<ApiAccessibleAuditLog>(); + +export const auditLogAccessibleColumns = [ + columnHelper.accessor("auditLog.date", { + header: "Erstellt am", + cell: (props) => formatDate(props.getValue()), + enableSorting: false, + }), + columnHelper.accessor("auditLog.source", { + header: "Modul", + cell: (props) => auditLogSourceNames[props.getValue()], + enableSorting: false, + }), + columnHelper.accessor("expiresAt", { + header: "Status", + cell: (props) => { + return ( + <Chip color="primary"> + Freigegeben bis {formatDate(props.getValue())} + </Chip> + ); + }, + enableSorting: false, + }), + columnHelper.display({ + header: "Aktionen", + id: "show", + cell: () => { + return ( + <Typography + color="primary" + startDecorator={ + <VisibilityOutlined + size={"md"} + color="primary" + aria-label="anzeigen" + /> + } + > + Auditlog anzeigen + </Typography> + ); + }, + meta: { + width: 196, + }, + }), +]; diff --git a/employee-portal/src/lib/baseModule/components/auditlog/authorize/AuditLogAuthorizePage.tsx b/employee-portal/src/lib/auditlog/components/authorize/AuditLogAuthorizePage.tsx similarity index 91% rename from employee-portal/src/lib/baseModule/components/auditlog/authorize/AuditLogAuthorizePage.tsx rename to employee-portal/src/lib/auditlog/components/authorize/AuditLogAuthorizePage.tsx index 6b328b7f7e631efa241fea72841478223feb90bd..14cfc93a83d3e6e81e991e3d88966d1914d1b1b8 100644 --- a/employee-portal/src/lib/baseModule/components/auditlog/authorize/AuditLogAuthorizePage.tsx +++ b/employee-portal/src/lib/auditlog/components/authorize/AuditLogAuthorizePage.tsx @@ -7,9 +7,9 @@ import { format } from "date-fns"; +import { auditLogAuthorizeColumns } from "@/lib/auditlog/components/authorize/auditLogAuthorizeColumns"; +import { useAuditLogAdminFilterSettings } from "@/lib/auditlog/components/authorize/useAuditLogAdminFilterSettings"; import { useGetAvailableAuditLogs } from "@/lib/auditlog/queries/auditlog"; -import { auditLogAuthorizeColumns } from "@/lib/baseModule/components/auditlog/authorize/auditLogAuthorizeColumns"; -import { useAuditLogAdminFilterSettings } from "@/lib/baseModule/components/auditlog/authorize/useAuditLogAdminFilterSettings"; import { routes } from "@/lib/baseModule/shared/routes"; import { ButtonBar } from "@/lib/shared/components/buttons/ButtonBar"; import { FilterButton } from "@/lib/shared/components/buttons/FilterButton"; diff --git a/employee-portal/src/lib/baseModule/components/auditlog/authorize/AuditLogAuthorizeSidebar.tsx b/employee-portal/src/lib/auditlog/components/authorize/AuditLogAuthorizeSidebar.tsx similarity index 75% rename from employee-portal/src/lib/baseModule/components/auditlog/authorize/AuditLogAuthorizeSidebar.tsx rename to employee-portal/src/lib/auditlog/components/authorize/AuditLogAuthorizeSidebar.tsx index 90e360d48bef4bba245d4c520bf4fc70e55ef720..a46197ae7ceef8edad7d2e9ce7918d171fbeaf26 100644 --- a/employee-portal/src/lib/baseModule/components/auditlog/authorize/AuditLogAuthorizeSidebar.tsx +++ b/employee-portal/src/lib/auditlog/components/authorize/AuditLogAuthorizeSidebar.tsx @@ -6,6 +6,7 @@ import { ApiAuditLogSource, ApiAuditLogSourceFromJSON, + ApiGetAuditLogGrantedAccessesResponse, } from "@eshg/employee-portal-api/auditlog"; import { ApiUser } from "@eshg/employee-portal-api/base"; import { formatDate } from "@eshg/lib-portal/formatters/dateTime"; @@ -14,13 +15,17 @@ import { List, ListItem, Sheet, Stack, Typography } from "@mui/joy"; import { Formik } from "formik"; import { useParams, useRouter } from "next/navigation"; import { useRef } from "react"; +import { isEmpty } from "remeda"; -import { useGrantAuditLogAccess } from "@/lib/auditlog/mutations/auditlog"; -import { useGetGetValidAuditLogGrantees } from "@/lib/auditlog/queries/auditlog"; import { ErrorHints, UserAutoCompleteField, -} from "@/lib/baseModule/components/auditlog/authorize/UserAutoCompleteField"; +} from "@/lib/auditlog/components/authorize/UserAutoCompleteField"; +import { useGrantAuditLogAccess } from "@/lib/auditlog/mutations/auditlog"; +import { + useGetAuditLogGrantedAccesses, + useGetAuditLogGranteesCandidates, +} from "@/lib/auditlog/queries/auditlog"; import { routes } from "@/lib/baseModule/shared/routes"; import { auditLogSourceNames } from "@/lib/shared/components/auditlog/constants"; import { useConfirmationDialog } from "@/lib/shared/components/confirmationDialog/ConfirmationDialogProvider"; @@ -51,7 +56,11 @@ export function AuditLogAuthorizeSidebar({ const source = ApiAuditLogSourceFromJSON(sourceParam); const date = new Date(dateParam as string); - const { users } = useGetGetValidAuditLogGrantees(source, date).data; + const { users } = useGetAuditLogGranteesCandidates(source, date).data; + const { data: grantedAccessesResponse } = useGetAuditLogGrantedAccesses( + source, + date, + ); const router = useRouter(); const buildRoutePreservingSearchParams = @@ -120,12 +129,14 @@ export function AuditLogAuthorizeSidebar({ {({ errors, setFieldValue, values }) => ( <SidebarForm ref={formRef}> <SidebarContent title={"Freigabeoptionen"}> - <DetailsColumn> + <DetailsColumn sx={{ gap: 2 }}> <AuditLogSheet date={date} source={sourceParam} /> - <Stack gap={2}> - <Typography level="title-md" sx={{ mt: 4 }}> - Log File freigeben - </Typography> + <AuditLogGranteesSheet + grantedAccesses={grantedAccessesResponse.grantedAccesses} + resolvedUsers={grantedAccessesResponse.resolvedUsers} + /> + <Stack gap={2} sx={{ mt: 2 }}> + <Typography level="title-md">Log File freigeben</Typography> <Typography level="body-md"> Sie können die File nur für User mit der Rolle "Betriebsrat" freigeben. @@ -179,6 +190,47 @@ function AuditLogSheet({ ); } +function AuditLogGranteesSheet({ + grantedAccesses, + resolvedUsers, +}: ApiGetAuditLogGrantedAccessesResponse) { + return ( + <Sheet variant="soft"> + <Typography level="title-md">Laufende Freigaben</Typography> + + <Stack gap={1} mt={2}> + {!isEmpty(grantedAccesses) ? ( + grantedAccesses.map((access, index) => ( + <Sheet + variant="soft" + sx={{ backgroundColor: "white", padding: 1 }} + key={access.idOfGrantedUser} + data-testid={"grantee-" + index} + > + <Stack + direction="row" + alignItems="center" + justifyContent="space-between" + > + <Typography level="body-sm"> + {fullName(resolvedUsers[access.idOfGrantedUser])} + </Typography> + <Typography level="body-sm"> + bis {formatDate(access.expiresAt)} + </Typography> + </Stack> + </Sheet> + )) + ) : ( + <Sheet variant="soft" sx={{ backgroundColor: "white", padding: 1 }}> + <Typography level="body-sm">Keine Freigaben</Typography> + </Sheet> + )} + </Stack> + </Sheet> + ); +} + interface LogFileAuthorizeDescriptionProps { source: ApiAuditLogSource; date: string; diff --git a/employee-portal/src/lib/baseModule/components/auditlog/authorize/UserAutoCompleteField.tsx b/employee-portal/src/lib/auditlog/components/authorize/UserAutoCompleteField.tsx similarity index 100% rename from employee-portal/src/lib/baseModule/components/auditlog/authorize/UserAutoCompleteField.tsx rename to employee-portal/src/lib/auditlog/components/authorize/UserAutoCompleteField.tsx diff --git a/employee-portal/src/lib/baseModule/components/auditlog/authorize/auditLogAuthorizeColumns.tsx b/employee-portal/src/lib/auditlog/components/authorize/auditLogAuthorizeColumns.tsx similarity index 91% rename from employee-portal/src/lib/baseModule/components/auditlog/authorize/auditLogAuthorizeColumns.tsx rename to employee-portal/src/lib/auditlog/components/authorize/auditLogAuthorizeColumns.tsx index f321431b556f675c896e960bd89c23f3f01937a8..1542b16abde8b1ffb6e8399e80d9b4421d29cbcb 100644 --- a/employee-portal/src/lib/baseModule/components/auditlog/authorize/auditLogAuthorizeColumns.tsx +++ b/employee-portal/src/lib/auditlog/components/authorize/auditLogAuthorizeColumns.tsx @@ -5,7 +5,7 @@ "use client"; -import { formatDateTime } from "@eshg/lib-portal/formatters/dateTime"; +import { formatDate } from "@eshg/lib-portal/formatters/dateTime"; import { LockOpenOutlined } from "@mui/icons-material"; import { Chip } from "@mui/joy"; import { createColumnHelper } from "@tanstack/react-table"; @@ -18,7 +18,7 @@ const columnHelper = createColumnHelper<AuditLog>(); export const auditLogAuthorizeColumns = [ columnHelper.accessor("createdAt", { header: "Erstellt am", - cell: (props) => formatDateTime(props.getValue()), + cell: (props) => formatDate(props.getValue()), enableSorting: false, meta: { canNavigate: { parentRow: true }, diff --git a/employee-portal/src/lib/baseModule/components/auditlog/authorize/useAuditLogAdminFilterSettings.ts b/employee-portal/src/lib/auditlog/components/authorize/useAuditLogAdminFilterSettings.ts similarity index 100% rename from employee-portal/src/lib/baseModule/components/auditlog/authorize/useAuditLogAdminFilterSettings.ts rename to employee-portal/src/lib/auditlog/components/authorize/useAuditLogAdminFilterSettings.ts diff --git a/employee-portal/src/lib/baseModule/components/auditlog/crypto.ts b/employee-portal/src/lib/auditlog/components/crypto.ts similarity index 99% rename from employee-portal/src/lib/baseModule/components/auditlog/crypto.ts rename to employee-portal/src/lib/auditlog/components/crypto.ts index 7748375fe55058c80a36edeb3ac4e0e7aa90c3f1..f0db3306c70d302bc9a80f5fccfa1daeace84870 100644 --- a/employee-portal/src/lib/baseModule/components/auditlog/crypto.ts +++ b/employee-portal/src/lib/auditlog/components/crypto.ts @@ -12,7 +12,7 @@ export async function generateKeyPairs( const suite = new CipherSuite({ kem: KemId.DhkemP256HkdfSha256, kdf: KdfId.HkdfSha256, - aead: AeadId.Aes128Gcm, + aead: AeadId.Aes256Gcm, }); const keyPair = await suite.kem.generateKeyPair(); diff --git a/employee-portal/src/lib/auditlog/queries/auditlog.ts b/employee-portal/src/lib/auditlog/queries/auditlog.ts index 9fbc59ec5cc7bd16b0878603b57ad5bba73a2441..356ccb4f9aaafeb5e8874cda1db30b749b60baa6 100644 --- a/employee-portal/src/lib/auditlog/queries/auditlog.ts +++ b/employee-portal/src/lib/auditlog/queries/auditlog.ts @@ -5,17 +5,16 @@ import { ApiAuditLogSource, + GetAuditLogGrantedAccessesRequest, + GetAuditLogGranteesCandidatesRequest, GetAvailableLogsRequest, - GetValidAuditLogGranteesRequest, } from "@eshg/employee-portal-api/auditlog"; -import { queryKeyFactory } from "@eshg/lib-portal/api/queryKeyFactory"; import { unwrapRawResponse } from "@eshg/lib-portal/api/unwrapRawResponse"; import { useSuspenseQuery } from "@tanstack/react-query"; import { useAuditlogApi } from "@/lib/auditlog/api/clients"; import { mapResponse } from "@/lib/auditlog/api/models/auditlog"; - -const auditlogQueryKey = queryKeyFactory(["auditlog"]); +import { auditLogApiQueryKey } from "@/lib/auditlog/queries/queryKeys"; export const SearchParamsKeys = { source: "source", @@ -45,7 +44,7 @@ export function useGetAvailableAuditLogs(params: SearchParams) { }; return useSuspenseQuery({ - queryKey: auditlogQueryKey([ + queryKey: auditLogApiQueryKey([ "available", request, Array.from(request.source ?? new Set()), @@ -56,20 +55,51 @@ export function useGetAvailableAuditLogs(params: SearchParams) { }); } -export function useGetGetValidAuditLogGrantees( +export function useGetAuditLogGranteesCandidates( source: ApiAuditLogSource, date: Date, ) { const auditlogApi = useAuditlogApi(); - const request: GetValidAuditLogGranteesRequest = { + const request: GetAuditLogGranteesCandidatesRequest = { source: source, date: date, }; return useSuspenseQuery({ - queryKey: auditlogQueryKey(["grantees", request]), + queryKey: auditLogApiQueryKey(["granteesCandidates", request]), queryFn: () => - auditlogApi.getValidAuditLogGranteesRaw(request).then(unwrapRawResponse), + auditlogApi + .getAuditLogGranteesCandidatesRaw(request) + .then(unwrapRawResponse), + }); +} + +export function useGetAuditLogGrantedAccesses( + source: ApiAuditLogSource, + date: Date, +) { + const auditlogApi = useAuditlogApi(); + + const request: GetAuditLogGrantedAccessesRequest = { + source: source, + date: date, + }; + + return useSuspenseQuery({ + queryKey: auditLogApiQueryKey(["grantAccess", request]), + queryFn: () => + auditlogApi + .getAuditLogGrantedAccessesRaw(request) + .then(unwrapRawResponse), + }); +} + +export function useGetAccessibleAuditLogs() { + const auditlogApi = useAuditlogApi(); + + return useSuspenseQuery({ + queryKey: auditLogApiQueryKey(["accessible"]), + queryFn: () => auditlogApi.getAccessibleAuditLogs(), }); } diff --git a/employee-portal/src/lib/auditlog/queries/featureToggles.ts b/employee-portal/src/lib/auditlog/queries/featureToggles.ts new file mode 100644 index 0000000000000000000000000000000000000000..8ec6b5b7191d146764a3a10c9d9367d456bff510 --- /dev/null +++ b/employee-portal/src/lib/auditlog/queries/featureToggles.ts @@ -0,0 +1,31 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + ApiAuditLogFeature, + ApiGetAuditLogFeatureTogglesResponse, +} from "@eshg/employee-portal-api/auditlog"; +import { + selectEnabledNewFeature, + useGetFeatureToggle, +} from "@eshg/lib-portal/api/featureToggles"; + +import { useFeatureTogglesApi } from "@/lib/auditlog/api/clients"; +import { auditLogFeatureTogglesApiQueryKey } from "@/lib/auditlog/queries/queryKeys"; + +export function useIsNewFeatureEnabled(name: ApiAuditLogFeature) { + return useGetAuditLogFeatureToggle(selectEnabledNewFeature(name)); +} + +function useGetAuditLogFeatureToggle<TValue>( + select: (featureToggles: ApiGetAuditLogFeatureTogglesResponse) => TValue, +): TValue { + const featureTogglesApi = useFeatureTogglesApi(); + return useGetFeatureToggle({ + queryKey: auditLogFeatureTogglesApiQueryKey(["getFeatureToggles"]), + queryFn: () => featureTogglesApi.getFeatureToggles(), + select, + }); +} diff --git a/employee-portal/src/lib/auditlog/queries/queryKeys.ts b/employee-portal/src/lib/auditlog/queries/queryKeys.ts new file mode 100644 index 0000000000000000000000000000000000000000..62429f62bf0eef8558d29f371b509f9f3467dde4 --- /dev/null +++ b/employee-portal/src/lib/auditlog/queries/queryKeys.ts @@ -0,0 +1,16 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { queryKeyFactory } from "@eshg/lib-portal/api/queryKeyFactory"; + +const apiQueryKey = queryKeyFactory(["auditlog"]); + +export const auditLogApiQueryKey = queryKeyFactory( + apiQueryKey(["auditLogApi"]), +); + +export const auditLogFeatureTogglesApiQueryKey = queryKeyFactory( + apiQueryKey(["auditLogFeatureTogglesApi"]), +); diff --git a/employee-portal/src/lib/baseModule/api/clients.ts b/employee-portal/src/lib/baseModule/api/clients.ts index 00bc3b3a79c7865a5af32360f9b89ed40403fd24..9603403ae8d89c9d7a5a9794cc63c7ef2cc08002 100644 --- a/employee-portal/src/lib/baseModule/api/clients.ts +++ b/employee-portal/src/lib/baseModule/api/clients.ts @@ -21,6 +21,7 @@ import { ResourceApi, StreetApi, TaskAggregationApi, + TaskMetricsApi, UserApi, } from "@eshg/employee-portal-api/base"; import { useApiConfiguration } from "@eshg/lib-portal/api/ApiProvider"; @@ -102,6 +103,11 @@ export function useProcedureAggregationApi() { return new ProcedureAggregationApi(configuration); } +export function useTaskMetricsApi() { + const configuration = useConfiguration(); + return new TaskMetricsApi(configuration); +} + export function useNotificationAggregationApi() { const configuration = useConfiguration(); return new NotificationAggregationApi(configuration); diff --git a/employee-portal/src/lib/baseModule/api/queries/apiQueryKey.ts b/employee-portal/src/lib/baseModule/api/queries/apiQueryKey.ts index b9923a9fc282f1d77026fc644eb7115ae50238f1..669728bb2dc626a21a3a521d8db2fd09db9c46c8 100644 --- a/employee-portal/src/lib/baseModule/api/queries/apiQueryKey.ts +++ b/employee-portal/src/lib/baseModule/api/queries/apiQueryKey.ts @@ -37,6 +37,10 @@ export const procedureApiQueryKey = queryKeyFactory( baseApiQueryKey(["procedure-aggregation-api"]), ); +export const taskMetricsApiQueryKey = queryKeyFactory( + baseApiQueryKey(["task-metrics-api"]), +); + export const notificationsApiQueryKey = queryKeyFactory( baseApiQueryKey(["notifications-api"]), ); diff --git a/employee-portal/src/lib/baseModule/api/queries/taskMetrics.ts b/employee-portal/src/lib/baseModule/api/queries/taskMetrics.ts new file mode 100644 index 0000000000000000000000000000000000000000..62bcb4abc869576871072818fa39322da8aef5b5 --- /dev/null +++ b/employee-portal/src/lib/baseModule/api/queries/taskMetrics.ts @@ -0,0 +1,22 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { GetTaskMetricsRequest } from "@eshg/employee-portal-api/base"; +import { unwrapRawResponse } from "@eshg/lib-portal/api/unwrapRawResponse"; +import { useSuspenseQuery } from "@tanstack/react-query"; + +import { useTaskMetricsApi } from "@/lib/baseModule/api/clients"; + +import { taskMetricsApiQueryKey } from "./apiQueryKey"; + +export function useTaskMetricsQuery(request: GetTaskMetricsRequest) { + const taskMetricsApi = useTaskMetricsApi(); + const queryResult = useSuspenseQuery({ + queryKey: taskMetricsApiQueryKey(["getTaskMetricsRaw", request]), + queryFn: () => + taskMetricsApi.getTaskMetricsRaw(request).then(unwrapRawResponse), + }); + return queryResult.data; +} diff --git a/employee-portal/src/lib/baseModule/api/queries/users.ts b/employee-portal/src/lib/baseModule/api/queries/users.ts index efc067def1f9ab8d137604d1b233fa976dc0fdf3..8161819d2c18b97a82d9dfe21018d9266f5344e1 100644 --- a/employee-portal/src/lib/baseModule/api/queries/users.ts +++ b/employee-portal/src/lib/baseModule/api/queries/users.ts @@ -3,6 +3,8 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { GetSelfEventsRequest } from "@eshg/employee-portal-api/base"; +import { unwrapRawResponse } from "@eshg/lib-portal/api/unwrapRawResponse"; import { PortalErrorCode } from "@eshg/lib-portal/errorHandling/PortalErrorCode"; import { resolveError } from "@eshg/lib-portal/errorHandling/errorResolvers"; import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; @@ -23,9 +25,18 @@ export function useGetUserProfile(id: string) { export function useGetUsersByGroupQuery( groupName: string, getInitOverrides?: (inspectionId?: string) => RequestInit, +) { + return useSuspenseQuery( + useGetUsersByGroupQueryOptions(groupName, getInitOverrides), + ); +} + +export function useGetUsersByGroupQueryOptions( + groupName: string, + getInitOverrides?: (inspectionId?: string) => RequestInit, ) { const usersApi = useUserApi(); - return useSuspenseQuery({ + return queryOptions({ queryKey: userApiQueryKey(["getUsersByGroup", groupName]), queryFn: () => usersApi.getUsersByGroup(groupName, getInitOverrides?.()), }); @@ -112,3 +123,11 @@ export function useGetSelfActiveSessions() { queryFn: () => userApi.getSelfActiveSessions(), }); } + +export function useGetSelfUserEvents(request: GetSelfEventsRequest) { + const userApi = useUserApi(); + return useSuspenseQuery({ + queryKey: userApiQueryKey(["getSelfUserEvents", request]), + queryFn: () => userApi.getSelfEventsRaw(request).then(unwrapRawResponse), + }); +} diff --git a/employee-portal/src/lib/baseModule/components/StaticTextDocumentPanel.tsx b/employee-portal/src/lib/baseModule/components/StaticTextDocumentPanel.tsx new file mode 100644 index 0000000000000000000000000000000000000000..1e7ccd34d1195467fdd10f28176ca409f6442db1 --- /dev/null +++ b/employee-portal/src/lib/baseModule/components/StaticTextDocumentPanel.tsx @@ -0,0 +1,59 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { ExternalLink } from "@eshg/lib-portal/components/navigation/ExternalLink"; +import { Stack, StackProps, Typography } from "@mui/joy"; + +import { ContentPanel } from "@/lib/shared/components/contentPanel/ContentPanel"; + +export function NoWrap({ children }: { children: string }) { + return ( + <Typography component={"span"} noWrap sx={{ display: "inline" }}> + {children} + </Typography> + ); +} + +export function LinkInNewTab({ + href, + children, +}: { + href: string; + children: string; +}) { + return ( + <ExternalLink href={href} target={"_blank"}> + {children} + </ExternalLink> + ); +} + +export function StaticTextDocumentPanel(props: StackProps) { + return ( + <ContentPanel> + <Stack + gap={4} + sx={{ + "& :where(p, span)": { + maxWidth: "750px", + textWrap: "pretty", + hyphens: "auto", + }, + "& :where(h2, h3)": { + maxWidth: "750px", + textWrap: "balance", + hyphens: "auto", + }, + "& a": { + maxWidth: "fit-content", + textWrap: "nowrap", + hyphens: "none", + }, + }} + {...props} + /> + </ContentPanel> + ); +} diff --git a/employee-portal/src/lib/baseModule/components/accessibility/Accessibility.tsx b/employee-portal/src/lib/baseModule/components/accessibility/Accessibility.tsx index c78a88f0afe6ae503d47935a1056152fac256592..05771967abd1d3019c4060dc5990e60802241ab9 100644 --- a/employee-portal/src/lib/baseModule/components/accessibility/Accessibility.tsx +++ b/employee-portal/src/lib/baseModule/components/accessibility/Accessibility.tsx @@ -3,13 +3,169 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { ContentPanel } from "@/lib/shared/components/contentPanel/ContentPanel"; +import { List, ListItem, Stack, Typography, TypographyProps } from "@mui/joy"; + +import { + LinkInNewTab, + StaticTextDocumentPanel, +} from "@/lib/baseModule/components/StaticTextDocumentPanel"; + +function Emphasis(props: TypographyProps) { + return <Typography fontWeight={600} {...props} />; +} export function Accessibility() { return ( - <ContentPanel> - Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie - vom Gesundheitsamt freigegeben sind. - </ContentPanel> + <StaticTextDocumentPanel> + <Typography> + Diese Erklärung zur digitalen Barrierefreiheit gilt für die unter ep. + <Emphasis>frankfurt.ga-lotse.de</Emphasis> veröffentlichte Webseite. + <br /> + <br /> + Als öffentliche Stelle im Sinne der Richtlinie (EU) 2016/2102 sind wir + bemüht, unsere Websites und mobilen Anwendungen im Einklang mit den + Bestimmungen des Hessischen Behinderten-Gleichstellungsgesetzes + (HessBGG) sowie der Hessischen Verordnung über barrierefreie + Informationstechnik (BITV HE 2019) zur Umsetzung der Richtlinie (EU) + 2016/2102 barrierefrei zugänglich zu machen. Frankfurt.ga-lotse.de ist + überwiegend mit den derzeit gültigen Vorschriften zur Barrierefreiheit + (BITV 2.0, 2019/WCAG 2.1) vereinbar. Inhalte und Funktionen, die dem + derzeit noch nicht vollständig entsprechen, sind nachfolgend aufgeführt. + </Typography> + + <Stack + component={"section"} + aria-labelledby={"agreement-requirements"} + gap={1} + > + <Typography level={"h2"} id={"agreement-requirements"}> + Stand der Vereinbarkeit mit den Anforderungen + </Typography> + <Typography> + Die Anforderungen der Barrierefreiheit ergeben sich aus § 3 Absätze 1 + bis 4 und § 4 der BITV HE 2019, die auf Grundlage von § 14 des HessBGG + erlassen wurde. + <br /> + <br /> + Die Ãœberprüfung der Einhaltung der Anforderungen beruht auf einer am + 23.09.2024 durchgeführten Selbstbewertung. + </Typography> + </Stack> + + <Stack component={"section"} aria-labelledby={"accessibility-exemptions"}> + <Typography level={"h2"} id={"accessibility-exemptions"}> + Nicht barrierefreie Inhalte{" "} + </Typography> + <Typography> + Aufgrund der Ãœberprüfung ist die <Emphasis>Website</Emphasis> mit den + zuvor genannten Anforderungen <Emphasis>nur teilweise</Emphasis>{" "} + vereinbar. + </Typography> + <List marker={"disc"}> + <ListItem> + <Emphasis>PDF-Dateien sind nicht vollständig barrierefrei</Emphasis> + </ListItem> + <ListItem> + <Emphasis>Nicht alle Schaltflächen haben erkennbaren Text</Emphasis> + </ListItem> + <ListItem> + <Emphasis> + Es gibt Schaltflächen mit zu kleinen Klickflächen für Touch-Geräte + </Emphasis> + </ListItem> + <ListItem> + <Emphasis>Nicht alle Formelemente haben eine Beschriftung</Emphasis> + </ListItem> + </List> + <Emphasis> + Die Stadt Frankfurt am Main arbeitet daran, die barrierefreien + Angebote weiter auszubauen. + </Emphasis> + </Stack> + + <Stack + component={"section"} + aria-labelledby={"date-of-accessibility-verification"} + > + <Typography level={"h2"} id={"date-of-accessibility-verification"}> + Datum der Erstellung der Erklärung zur Barrierefreiheit + </Typography> + <Typography> + Diese Erklärung wurde am <Emphasis>23.09.2024</Emphasis> erstellt und + zuletzt am <Emphasis>23.09.2024</Emphasis> überprüft und aktualisiert. + </Typography> + </Stack> + + <Stack component={"section"} id={"feedback-and-suggestions"}> + <Typography level={"h2"} aria-labelledby={"feedback-and-suggestions"}> + Feedback und Anfragen zur digitalen Barrierefreiheit + </Typography> + <Typography> + Sie möchten uns noch bestehende Barrieren mitteilen oder nicht + barrierefreie Inhalte in einem barrierefreien Format anfordern? + Sprechen Sie unsere verantwortlichen Kontaktpersonen an: + </Typography> + <Emphasis> + Gesundheitsamt Frankfurt am Main + <br /> + Digitale Zukunft, IT und strategische Planung + <br /> + +49 (0) 800 -4256873 + </Emphasis> + <LinkInNewTab href={"mailto:support@ga-lotse.de"}> + support@ga-lotse.de + </LinkInNewTab> + </Stack> + + <Stack component={"section"} aria-labelledby={"feedback-procedure"}> + <Typography level={"h2"} id={"feedback-procedure"}> + Durchsetzungsverfahren + </Typography> + <Typography> + Wenn auch nach Ihrem Feedback an den oben genannten Kontakt keine + zufriedenstellende Lösung gefunden wurde, können Sie die + Durchsetzungs- und Ãœberwachungsstelle Barrierefreie + Informationstechnik einschalten. Sie haben nach Ablauf einer Frist von + sechs Wochen das Recht sich direkt an die Durchsetzungs- und + Ãœberwachungsstelle zu wenden. Unter Einbeziehung aller Beteiligten + versucht die Durchsetzungsstelle, die Umstände der fehlenden + Barrierefreiheit zu ermitteln, damit der Träger diese beheben kann. + </Typography> + </Stack> + + <Stack component={"section"} aria-labelledby={"contact"}> + <Typography level={"h2"} id={"contact"}> + Durchsetzungs- und Ãœberwachungsstelle Barrierefreie + Informationstechnik Hessisches Ministerium für Soziales und + Integration Sitz: Regierungspräsidium Gießen + </Typography> + <Typography> + Prof. Dr. Erdmuthe Meyer zu Bexten + <br /> + Landesbeauftragte für barrierefreie IT + <br /> + Leiterin der Durchsetzungs- und Ãœberwachungsstelle + <br /> + Landgraf-Philipp-Platz 1-7 + <br /> + 35390 Gießen + <br /> + Telefon: +49 641 303 - 2901 + <br /> + E-Mail:{" "} + <LinkInNewTab href={"mailto:Durchsetzungsstelle-LBIT@rpgi.hessen.de"}> + Durchsetzungsstelle-LBIT@rpgi.hessen.de + </LinkInNewTab> + </Typography> + </Stack> + + <LinkInNewTab + href={ + "https://lbit.hessen.de/Durchsetzungs-und-Ueberwachungsstelle/Durchsetzungsverfahren-beantragen/Formular-Durchsetzungsverfahren" + } + > + Durchsetzung beantragen + </LinkInNewTab> + </StaticTextDocumentPanel> ); } diff --git a/employee-portal/src/lib/baseModule/components/acknowledgements/Acknowledgements.tsx b/employee-portal/src/lib/baseModule/components/acknowledgements/Acknowledgements.tsx index 43790c219113b9611639147ee322dfae659e24dd..6437b9dabae16f1ec2e1c5e7bbbc2f276eb77a90 100644 --- a/employee-portal/src/lib/baseModule/components/acknowledgements/Acknowledgements.tsx +++ b/employee-portal/src/lib/baseModule/components/acknowledgements/Acknowledgements.tsx @@ -3,13 +3,114 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { ContentPanel } from "@/lib/shared/components/contentPanel/ContentPanel"; +import { Stack, Typography } from "@mui/joy"; +import { PropsWithChildren } from "react"; + +import { + LinkInNewTab, + StaticTextDocumentPanel, +} from "@/lib/baseModule/components/StaticTextDocumentPanel"; + +function Section({ + title, + id, + sourceHref, + hint, + children, +}: PropsWithChildren<{ + title: string; + id: string; + sourceHref: string; + hint?: string; +}>) { + return ( + <Stack component={"section"} aria-labelledby={id}> + <Typography component={"h2"} level={"title-md"} id={id}> + {title} + </Typography> + <Typography>{children}</Typography> + <LinkInNewTab href={sourceHref}>Herkunft</LinkInNewTab> + {hint && <Typography sx={{ marginTop: 1 }}>{hint}</Typography>} + </Stack> + ); +} export function Acknowledgements() { return ( - <ContentPanel> - Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie - vom Gesundheitsamt freigegeben sind. - </ContentPanel> + <StaticTextDocumentPanel> + GA-Lotse verwendet die folgenden externen Ressourcen und Datenbanken: + <Section + id={"street-directory"} + title={"Straßenverzeichnis der Stadt Frankfurt am Main"} + sourceHref={ + "https://www.offenedaten.frankfurt.de/dataset/strassenverzeichnis-der-stadt-frankfurt-am-main" + } + hint={ + "Hinweis: An den Daten wurden an zwei Stellen Veränderungen vorgenommen. Zwei Straßen wurden entfernt." + } + > + Datenlizenz Deutschland Namensnennung + </Section> + <Section + id={"osm-map-data-extracts"} + title={"Open Street Map Data Extracts"} + sourceHref={"https://download.geofabrik.de/"} + > + CC BY-SA 2.0 + </Section> + <Section + title={"Open Street Map Umrechnung Straßen / Geokoordinaten"} + id={"osm-geocoordinate-resolver"} + sourceHref={"https://nominatim.openstreetmap.org/"} + > + CC BY-SA 3.0 + </Section> + <Section + id={"osm-route-planner"} + title={"Open Street Map Routenplaner"} + sourceHref={"https://routing.openstreetmap.de/"} + > + CC BY-SA 3.0 + </Section> + <Section + title={"ICD-10 Codes"} + id={"icd-10-codes"} + sourceHref={ + "https://klassifikationen.bfarm.de/icd-10-gm/kode-suche/htmlgm2024/index.htm" + } + > + Die Erstellung erfolgt unter Verwendung der maschinenlesbaren Fassung + des Bundesinstituts für Arzneimittel und Medizinprodukte (BfArM). + </Section> + <Section + title={ + "Referenzperzentile für anthropometrische Maßzahlen und Blutdruck aus der Studie zur Gesundheit von Kindern und Jugendlichen in Deutschland (KiGGS)" + } + id={"kiggs-reference"} + sourceHref={"http://dx.doi.org/10.25646/3179"} + > + 2013, Neuhauser, Hannelore and Schienkiewitz, Anja and Rosario, Angelika + Schaffrath and Dortschy, Reinhard and Kurth, Bärbel-Maria + </Section> + <Stack + component={"section"} + aria-labelledby={"software-dependencies"} + gap={2} + > + <Typography level={"h2"} id={"software-dependencies"}> + Verwendete Libraries + </Typography> + <Typography> + Verwendete Open Source Bibliotheken finden sich in den jeweiligen + Paketen im Repository auf{" "} + <LinkInNewTab + href={"https://gitlab.opencode.de/ga-lotse/ga-lotse-code"} + > + OpenCoDE + </LinkInNewTab> + . + </Typography> + </Stack> + </StaticTextDocumentPanel> ); } diff --git a/employee-portal/src/lib/baseModule/components/contact/Contact.tsx b/employee-portal/src/lib/baseModule/components/contact/Contact.tsx index 7b24b0bc68e4b4c08b2b3e9d0d74e10ba41baf4c..b0e233f1c05f8b61b6cfbaf292d91b4c2561a401 100644 --- a/employee-portal/src/lib/baseModule/components/contact/Contact.tsx +++ b/employee-portal/src/lib/baseModule/components/contact/Contact.tsx @@ -3,13 +3,47 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { ContentPanel } from "@/lib/shared/components/contentPanel/ContentPanel"; +import { ExternalLink } from "@eshg/lib-portal/components/navigation/ExternalLink"; +import { Stack, Typography } from "@mui/joy"; + +import { + LinkInNewTab, + StaticTextDocumentPanel, +} from "@/lib/baseModule/components/StaticTextDocumentPanel"; export function Contact() { return ( - <ContentPanel> - Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie - vom Gesundheitsamt freigegeben sind. - </ContentPanel> + <StaticTextDocumentPanel> + <Stack component={"section"} aria-labelledby={"phone-contact"} gap={1}> + <Stack> + <Typography component={"h2"} level={"title-md"} id={"phone-contact"}> + Telefonische Erreichbarkeit: + </Typography> + <Typography>Telefon: +49 (0) 800 -4256873</Typography> + </Stack> + <Typography> + Montag - Donnerstag: 07:30 Uhr - 16:00 Uhr + <br /> + Freitag: 07:30 Uhr - 14:00 Uhr + </Typography> + </Stack> + <Stack component={"section"} aria-labelledby={"ticket-contact"}> + <Typography component={"h2"} level={"title-md"} id={"ticket-contact"}> + Erreichbarkeit via Ticketsystem: + </Typography> + <Typography> + E-Mail:{" "} + <ExternalLink href={"mailto:support@ga-lotse.de"}> + support@ga-lotse.de + </ExternalLink> + </Typography> + </Stack> + <Typography> + Open Source:{" "} + <LinkInNewTab href={"https://gitlab.opencode.de/ga-lotse"}> + OpenCoDE + </LinkInNewTab> + </Typography> + </StaticTextDocumentPanel> ); } diff --git a/employee-portal/src/lib/baseModule/components/imprint/Imprint.tsx b/employee-portal/src/lib/baseModule/components/imprint/Imprint.tsx deleted file mode 100644 index 2e8f80d5ca08fba23fe56e475e2d575a7a435c98..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/baseModule/components/imprint/Imprint.tsx +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { ContentPanel } from "@/lib/shared/components/contentPanel/ContentPanel"; - -export function Imprint() { - return ( - <ContentPanel> - Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie - vom Gesundheitsamt freigegeben sind. - </ContentPanel> - ); -} diff --git a/employee-portal/src/lib/baseModule/components/layout/SelfUserSidebar.tsx b/employee-portal/src/lib/baseModule/components/layout/SelfUserSidebar.tsx index 3629bac1aa4148757f73d8c09cf01ea84533f794..57bc2172779cc37a37e44e5720495c6d9848f472 100644 --- a/employee-portal/src/lib/baseModule/components/layout/SelfUserSidebar.tsx +++ b/employee-portal/src/lib/baseModule/components/layout/SelfUserSidebar.tsx @@ -9,6 +9,7 @@ import { InternalLinkButton } from "@eshg/lib-portal/components/navigation/Inter import ProfileIcon from "@mui/icons-material/AccountCircle"; import DevicesIcon from "@mui/icons-material/Devices"; import LogoutIcon from "@mui/icons-material/Logout"; +import ManageSearchIcon from "@mui/icons-material/ManageSearch"; import { Button, Divider, Stack } from "@mui/joy"; import { usePathname } from "next/navigation"; import { ReactNode, useEffect } from "react"; @@ -70,6 +71,9 @@ export function SelfUserSidebar({ const isActiveSessionsEnabled = useIsNewFeatureEnabled( ApiBaseFeature.AccountActiveSessions, ); + const isLoginProtocolEnabled = useIsNewFeatureEnabled( + ApiBaseFeature.LoginProtocol, + ); const { data: selfUser } = useGetSelfUser(); const pathname = usePathname(); @@ -100,6 +104,15 @@ export function SelfUserSidebar({ </NavLinkButton> )} + {isLoginProtocolEnabled && ( + <NavLinkButton + href={routes.account.loginProtocol} + decorator={<ManageSearchIcon />} + > + Anmeldeprotokoll + </NavLinkButton> + )} + <Divider orientation="horizontal" /> </Stack> @@ -112,6 +125,10 @@ export function SelfUserSidebar({ href={routes.privacy} label="Datenschutzerklärung" /> + <MiscLinkButton + href={routes.usageNotes} + label={"Nutzungshinweise"} + /> <MiscLinkButton href={routes.acknowledgements} label="Danksagung" /> <MiscLinkButton href={routes.contact} label="Kontakt" /> <MiscLinkButton href={routes.releaseNotes} label="Release Notes" /> diff --git a/employee-portal/src/lib/baseModule/components/layout/messagesSidebar/MessageNotification.tsx b/employee-portal/src/lib/baseModule/components/layout/messagesSidebar/MessageNotification.tsx index 23cc3b2312d56768edb02137cdc29f626b972feb..9bce0ece5ee2933651478307373e7eea5354d186 100644 --- a/employee-portal/src/lib/baseModule/components/layout/messagesSidebar/MessageNotification.tsx +++ b/employee-portal/src/lib/baseModule/components/layout/messagesSidebar/MessageNotification.tsx @@ -11,8 +11,6 @@ import { Avatar, Card, IconButton, Stack, Typography } from "@mui/joy"; import { Formik } from "formik"; import { User } from "matrix-js-sdk/lib/matrix"; -import { BadgeAvatar } from "@/lib/businessModules/chat/components/BadgeAvatar"; -import { useGetUsersPresence } from "@/lib/businessModules/chat/shared/hooks/useGetUsersPresence"; import { useSendMessage } from "@/lib/businessModules/chat/shared/hooks/useSendMessage"; import { Message } from "@/lib/businessModules/chat/shared/types"; import { formatDateTimeRangeToNow } from "@/lib/shared/helpers/dateTime"; @@ -25,15 +23,12 @@ export function MessageNotification({ sender: User | null; }) { const { sendMessage } = useSendMessage(); - const usersPresence = useGetUsersPresence(); return ( <Card variant="soft" data-testid="notification" size="sm"> <Stack direction="row" spacing={1}> <Stack direction="row" alignItems="start"> - <BadgeAvatar status={usersPresence[sender?.userId ?? ""]}> - <Avatar src={sender?.avatarUrl} /> - </BadgeAvatar> + <Avatar src={sender?.avatarUrl} /> </Stack> <Stack width="100%"> <Stack diff --git a/employee-portal/src/lib/baseModule/components/privacy/Privacy.tsx b/employee-portal/src/lib/baseModule/components/privacy/Privacy.tsx index c7170cfa7a07a1ae7f3f2ce46550188efb91af76..0bfb6eef2f700a8a8fc5a6af99cf7497ab71f9a1 100644 --- a/employee-portal/src/lib/baseModule/components/privacy/Privacy.tsx +++ b/employee-portal/src/lib/baseModule/components/privacy/Privacy.tsx @@ -3,13 +3,369 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { ContentPanel } from "@/lib/shared/components/contentPanel/ContentPanel"; +import { ExternalLink } from "@eshg/lib-portal/components/navigation/ExternalLink"; +import { List, ListItem, Stack, Typography } from "@mui/joy"; +import { PropsWithChildren } from "react"; + +import { + NoWrap, + StaticTextDocumentPanel, +} from "@/lib/baseModule/components/StaticTextDocumentPanel"; + +function Section({ + id, + title, + children, +}: PropsWithChildren<{ id: string; title: string }>) { + return ( + <Stack + component={"section"} + aria-labelledby={id} + alignItems={"start"} + gap={1} + > + <Typography level={"h2"} id={id}> + {title} + </Typography> + {children} + </Stack> + ); +} export function Privacy() { return ( - <ContentPanel> - Die Seite ist noch im Aufbau. Die Inhalte werden aktualisiert, sobald sie - vom Gesundheitsamt freigegeben sind. - </ContentPanel> + <StaticTextDocumentPanel> + <Typography> + Diese Datenschutzerklärung gilt für die Webseite{" "} + <NoWrap>„frankfurt.ga-lotse.de“</NoWrap> (bzw.{" "} + <NoWrap>„https://frankfurt.ga-lotse.de“</NoWrap> sowie dazu zugehörige + Subdomains) des Gesundheitsamts der Stadt Frankfurt am Main. Dieses + Informationsportal bietet Informationen zu besonderen Ereignissen und + wird ausschließlich zum dem Zwecke genutzt. + </Typography> + + <Section + id={"section-1"} + title={ + "1. Name und Kontaktdaten des für die Verarbeitung Verantwortlichen sowie des behördlichen Datenschutzbeauftragten" + } + > + <Typography> + Diese Datenschutz-Information gilt für die Datenverarbeitung durch: + <br /> + <br /> + Verantwortlicher: + <br /> + <br /> + Verantwortlich für die Website{" "} + <NoWrap>„frankfurt.ga-lotse.de“</NoWrap> ist das Gesundheitsamt + Frankfurt am Main: + <br /> + <br /> + Gesundheitsamt Frankfurt am Main + <br /> + Breite Gasse 28 + <br /> + 60313 Frankfurt am Main + <br /> + E-Mail:{" "} + <ExternalLink + href={"mailto:datenschutz.gesundheitsamt@stadt-frankfurt.de"} + > + datenschutz.gesundheitsamt@stadt-frankfurt.de + </ExternalLink> + <br /> + <br /> + Behördlicher Datenschutzbeauftragter: + <br /> + <br /> + Referat Datenschutz und IT-Sicherheit + <br /> + Sandgasse 6, 60311 Frankfurt am Main + </Typography> + </Section> + + <Section + id={"section-2"} + title={ + "2. Erhebung und Speicherung personenbezogener Daten sowie Art und Zweck von deren Verwendung" + } + > + <Typography> + 2.1 Beim Besuch der Website + <br /> + <br /> + Beim Aufrufen unserer Website <NoWrap> + „frankfurt.ga-lotse.de“ + </NoWrap>{" "} + werden durch den auf Ihrem Endgerät zum Einsatz kommenden Browser + automatisch Informationen an den Server unserer Website gesendet. + Diese Informationen werden temporär in einem sog. Logfile gespeichert. + Folgende Informationen werden dabei ohne Ihr Zutun erfasst und bis zur + automatisierten Löschung gespeichert: + </Typography> + + <List marker={"disc"}> + <ListItem> + <Typography>IP-Adresse des anfragenden Rechners</Typography> + </ListItem> + <ListItem> + <Typography>Datum und Uhrzeit des Zugriffs</Typography> + </ListItem> + <ListItem> + <Typography>Name und URL der abgerufenen Datei</Typography> + </ListItem> + <ListItem> + <Typography> + Website, von der aus der Zugriff erfolgt (Referrer-URL) + </Typography> + </ListItem> + <ListItem> + <Typography> + verwendeter Browser und ggf. das Betriebssystem Ihres Rechners + sowie der Name Ihres Access-Providers + </Typography> + </ListItem> + </List> + + <Typography> + Die genannten Daten werden durch uns zu folgenden Zwecken verarbeitet: + </Typography> + + <List marker={"disc"}> + <ListItem> + <Typography> + Gewährleistung eines reibungslosen Verbindungsaufbaus der Website + </Typography> + </ListItem> + <ListItem> + <Typography> + Gewährleistung einer komfortablen Nutzung unserer Website + </Typography> + </ListItem> + <ListItem> + <Typography> + Auswertung der Systemsicherheit und -stabilität + </Typography> + </ListItem> + <ListItem> + <Typography>Rückverfolgung etwaiger DoS Attacken</Typography> + </ListItem> + <ListItem> + <Typography>sowie zu weiteren administrativen Zwecken</Typography> + </ListItem> + </List> + + <Typography level={"title-md"}> + 2.2 Beim Verwenden des QR-Codes + </Typography> + <Typography> + Falls Ihnen für den Zugang zum Online-Portal ein individualisierter + QR-Code gegeben wurde, hat dieser den Zweck, Informationen oder + Nachrichten speziell für Sie zur Verfügung zu stellen, beispielsweise + als betroffener eines gesundheitsrelevanten Ereignisses. Nach + Einscannen des Codes wird man direkt auf die entsprechende + Informationsseite weitergeleitet. Im System wird dabei protokolliert, + zu welchem Zeitpunkt der QR-Code verwendet wurde, jedoch ohne weitere + Angaben wie IP-Adresse oder Namen o.ä. + <br /> + <br /> + Die Rechtsgrundlage für die Datenverarbeitung ist{" "} + <NoWrap>Art. 6 Abs. 1 S. 1 lit. f DS-GVO</NoWrap>. Unser berechtigtes + Interesse folgt aus oben aufgelisteten Zwecken zur Datenerhebung. In + keinem Fall verwenden wir die erhobenen Daten zu dem Zweck, + Rückschlüsse auf Ihre Person zu ziehen. + <br /> + <br /> + Darüber hinaus setzen wir beim Besuch unserer Website Cookies ein. + Nähere Erläuterungen dazu erhalten Sie unter den Ziff. 4 dieser + Datenschutzerklärung. + <br /> + <br /> + </Typography> + </Section> + + <Section + id={"sharing-with-third-parties"} + title={"3. Weitergabe von Daten"} + > + <Typography> + Es findet keine Weitergabe von Daten an Dritte statt. + </Typography> + </Section> + + <Section id={"cookies"} title={"4. Cookies"}> + <Typography> + Wir setzen auf unserer Seite Cookies ein. Hierbei handelt es sich um + kleine Dateien, die Ihr Browser automatisch erstellt und die auf Ihrem + Endgerät (Laptop, Tablet, Smartphone o.ä.) gespeichert werden, wenn + Sie unsere Seite besuchen. Cookies richten auf Ihrem Endgerät keinen + Schaden an, enthalten keine Viren, Trojaner oder sonstige + Schadsoftware. + <br /> + <br /> + In dem Cookie werden Informationen abgelegt, die sich jeweils im + Zusammenhang mit dem spezifisch eingesetzten Endgerät ergeben. Dies + bedeutet jedoch nicht, dass wir dadurch unmittelbar Kenntnis von Ihrer + Identität erhalten. + <br /> + <br /> + Der Einsatz von Cookies dient einerseits dazu, die Nutzung unseres + Angebots für Sie angenehmer zu gestalten. So setzen wir sogenannte + Session-Cookies ein, um zu erkennen, dass Sie einzelne Seiten unserer + Website bereits besucht haben. Diese werden nach Verlassen unserer + Seite automatisch gelöscht. + <br /> + <br /> + Darüber hinaus setzen wir ebenfalls zur Optimierung der + Benutzerfreundlichkeit temporäre Cookies ein, die für einen bestimmten + festgelegten Zeitraum auf Ihrem Endgerät gespeichert werden. Besuchen + Sie unsere Seite erneut, um unsere Dienste in Anspruch zu nehmen, wird + automatisch erkannt, dass Sie bereits bei uns waren und welche + Eingaben und Einstellungen sie getätigt haben, um diese nicht noch + einmal eingeben zu müssen. + <br /> + <br /> + Die durch Cookies verarbeiteten Daten sind für die genannten Zwecke + zur Wahrung unserer berechtigten Interessen erforderlich. + <br /> + <br /> + Die meisten Browser akzeptieren Cookies automatisch. Sie können Ihren + Browser jedoch so konfigurieren, dass keine Cookies auf Ihrem Computer + gespeichert werden oder stets ein Hinweis erscheint, bevor ein neuer + Cookie angelegt wird. Die vollständige Deaktivierung von Cookies kann + jedoch dazu führen, dass Sie nicht alle Funktionen unserer Website + nutzen können. + </Typography> + </Section> + + <Section id={"analytic-tools"} title={"5. Analyse-Tools"}> + <Typography>Es werden keine Analyse-Tools verwendet.</Typography> + </Section> + + <Section id={"social-media-plugins"} title={"6. Social Media Plug-ins"}> + <Typography> + Es werden keine Social Media Plug-Ins verwendet. + </Typography> + </Section> + + <Section id={"rights-of-affected"} title={"7. Betroffenenrechte"}> + <Typography>Sie haben das Recht:</Typography> + <List marker={"disc"}> + <ListItem> + <Typography> + gemäß <NoWrap>Art. 15 DS-GVO</NoWrap> Auskunft über Ihre von uns + verarbeiteten personenbezogenen Daten zu verlangen. Insbesondere + können Sie Auskunft über die Verarbeitungszwecke, die Kategorie + der personenbezogenen Daten, die Kategorien von Empfängern, + gegenüber denen Ihre Daten offengelegt wurden oder werden, die + geplante Speicherdauer, das Bestehen eines Rechts auf + Berichtigung, Löschung, Einschränkung der Verarbeitung oder + Widerspruch, das Bestehen eines Beschwerderechts, die Herkunft + ihrer Daten, sofern diese nicht bei uns erhoben wurden sowie über + das Bestehen einer automatisierten Entscheidungsfindung + einschließlich Profiling und ggf. aussagekräftigen Informationen + zu deren Einzelheiten verlangen. + </Typography> + </ListItem> + <ListItem> + <Typography> + gemäß <NoWrap>Art. 16 DS-GVO</NoWrap> unverzüglich die + Berichtigung unrichtiger oder Vervollständigung Ihrer bei uns + gespeicherten personenbezogenen Daten zu verlangen. + </Typography> + </ListItem> + <ListItem> + <Typography> + gemäß <NoWrap>Art. 17 DS-GVO</NoWrap> die Löschung Ihrer bei uns + gespeicherten personenbezogenen Daten zu verlangen, soweit nicht + die Verarbeitung zur Ausübung des Rechts auf freie + Meinungsäußerung und Information, zur Erfüllung einer rechtlichen + Verpflichtung, aus Gründen des öffentlichen Interesses oder zur + Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen + erforderlich ist. + </Typography> + </ListItem> + <ListItem> + <Typography> + gemäß <NoWrap>Art. 18 DS-GVO</NoWrap> die Einschränkung der + Verarbeitung Ihrer personenbezogenen Daten zu verlangen, soweit + die Richtigkeit der Daten von Ihnen bestritten wird, die + Verarbeitung unrechtmäßig ist, Sie aber deren Löschung ablehnen + und wir die Daten nicht mehr benötigen, Sie jedoch diese zur + Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen + benötigen oder Sie gemäß <NoWrap>Art. 21 DS-GVO</NoWrap>{" "} + Widerspruch gegen die Verarbeitung eingelegt haben. + </Typography> + </ListItem> + <ListItem> + <Typography> + gemäß <NoWrap>Art. 20 DS-GVO</NoWrap> Ihre personenbezogenen + Daten, die Sie uns bereitgestellt haben, in einem strukturierten, + gängigen und maschinenlesebaren Format zu erhalten oder die + Ãœbermittlung an einen anderen Verantwortlichen zu verlangen. + </Typography> + </ListItem> + <ListItem> + <Typography> + gemäß <NoWrap>Art. 7 Abs. 3 DS-GVO</NoWrap> Ihre einmal erteilte + Einwilligung jederzeit gegenüber uns zu widerrufen. Dies hat zur + Folge, dass wir die Datenverarbeitung, die auf dieser Einwilligung + beruhte, für die Zukunft nicht mehr fortführen dürfen und + </Typography> + </ListItem> + <ListItem> + <Typography> + gemäß <NoWrap>Art. 77 DS-GVO</NoWrap> sich bei der zuständigen + Aufsichtsbehörde zu beschweren. Die zuständige Aufsichtsbehörde + ist: Der Hessische Datenschutzbeauftragte, Postfach 3163, 65021 + Wiesbaden, Telefon: 0611/1408 - 0, + poststelle@datenschutz-hessen.de. + </Typography> + </ListItem> + </List> + </Section> + + <Section id={"right-to-refute"} title={"8. Widerspruchsrecht"}> + <Typography> + Sofern Ihre personenbezogenen Daten auf Grundlage von berechtigten + Interessen gemäß <NoWrap>Art. 6 Abs. 1 S. 1 lit. f DS-GVO</NoWrap>{" "} + verarbeitet werden, haben Sie das Recht, gemäß{" "} + <NoWrap>Art. 21 DS-GVO</NoWrap> Widerspruch gegen die Verarbeitung + Ihrer personenbezogenen Daten einzulegen, soweit dafür Gründe + vorliegen, die sich aus Ihrer besonderen Situation ergeben. Möchten + Sie von Ihrem Widerrufs- oder Widerspruchsrecht Gebrauch machen, + genügt eine E-Mail an + <NoWrap>datenschutz.gesundheitsamt@stadt-frankfurt.de</NoWrap> . + </Typography> + </Section> + + <Section id={"data-safety"} title={"9. Datensicherheit"}> + <Typography> + Wir bedienen uns geeigneter technischer und organisatorischer + Sicherheitsmaßnahmen, um Ihre Daten gegen zufällige oder vorsätzliche + Manipulationen, teilweisen oder vollständigen Verlust, Zerstörung oder + gegen den unbefugten Zugriff Dritter zu schützen. Unsere + Sicherheitsmaßnahmen werden nach dem jeweiligen Stand der Technik + gemäß <NoWrap>Art. 32 DS-GVO</NoWrap> fortlaufend angepasst. + </Typography> + </Section> + + <Section id={"request-proceeding"} title={"10. Auftragsverarbeitung"}> + <Typography> + Es findet keine Auftragsverarbeitung der erhobenen Daten statt. + </Typography> + </Section> + + <Section + id={"recency-and-updates"} + title={"11. Aktualität und Änderung dieser Datenschutzerklärung"} + > + <Typography> + Diese Datenschutzerklärung ist aktuell gültig und hat den Stand + September 2024. + </Typography> + </Section> + </StaticTextDocumentPanel> ); } diff --git a/employee-portal/src/lib/baseModule/components/procedureMetrics/ProcedureMetricsDisplay.tsx b/employee-portal/src/lib/baseModule/components/procedureMetrics/ProcedureMetricsDisplay.tsx index 4eab006e7adad0a05fab6f1c61d779d9f060b73b..128eb37cf2d744e869904ba03062990674623ac5 100644 --- a/employee-portal/src/lib/baseModule/components/procedureMetrics/ProcedureMetricsDisplay.tsx +++ b/employee-portal/src/lib/baseModule/components/procedureMetrics/ProcedureMetricsDisplay.tsx @@ -5,6 +5,7 @@ "use client"; +import { ApiBaseFeature } from "@eshg/employee-portal-api/base"; import { ApiProcedureMetric } from "@eshg/employee-portal-api/inspection"; import { CheckOutlined, @@ -14,8 +15,13 @@ import { WarningAmberOutlined, } from "@mui/icons-material"; import { Stack, Typography } from "@mui/joy"; +import { endOfToday } from "date-fns"; +import { useState } from "react"; import { unique } from "remeda"; +import { useIsNewFeatureEnabled } from "@/lib/baseModule/api/queries/feature"; +import { useAggregateProcedureMetricsQuery } from "@/lib/baseModule/api/queries/procedures"; +import { routes } from "@/lib/baseModule/shared/routes"; import { FlashCard } from "@/lib/shared/components/cards/FlashCard"; import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; import { DataTable } from "@/lib/shared/components/table/DataTable"; @@ -23,12 +29,21 @@ import { TableSheet } from "@/lib/shared/components/table/TableSheet"; import { TimeRangeSelect } from "./TimeRangeSelect"; import { columnName, initialSorting, procedureMetricsColumns } from "./columns"; +import { lastXMonthsInDate } from "./rangeSelectHelper"; + +export function ProcedureMetricsDisplay() { + const timeRangeEnd = endOfToday(); + + const [selectedTimeRange, setSelectedTimeRange] = useState(12); + + const timeRangeStart = lastXMonthsInDate(timeRangeEnd, selectedTimeRange); + const { data: procedureMetrics } = useAggregateProcedureMetricsQuery({ + timeRangeStart, + timeRangeEnd, + }); + + const taskMetricsEnabled = useIsNewFeatureEnabled(ApiBaseFeature.TaskMetrics); -export function ProcedureMetricsDisplay(props: { - procedureMetrics: ApiProcedureMetric[]; - selectedTimeRange: number; - setSelectedTimeRange: (value: number) => void; -}) { function sumProcedureCounts( givenType: keyof Pick< ApiProcedureMetric, @@ -39,21 +54,21 @@ export function ProcedureMetricsDisplay(props: { | "openOrDraftCount" >, ) { - return props.procedureMetrics + return procedureMetrics .map((type) => type[givenType]) .reduce((a, b) => a + b, 0); } const uniqueBusinessModules = unique( - props.procedureMetrics.map((item) => item.businessModule), + procedureMetrics.map((item) => item.businessModule), ); return ( <Stack gap={3}> <TimeRangeSelect optionsInMonths={[1, 3, 6, 12]} - selectedTimeRange={props.selectedTimeRange} - setSelectedTimeRange={props.setSelectedTimeRange} + selectedTimeRange={selectedTimeRange} + setSelectedTimeRange={setSelectedTimeRange} /> <Stack role="list" direction="row" flexWrap="wrap" gap={2}> <FlashCard @@ -98,7 +113,7 @@ export function ProcedureMetricsDisplay(props: { </Typography> <TableSheet> <DataTable - data={props.procedureMetrics.filter( + data={procedureMetrics.filter( (procedure) => procedure.businessModule === businessModule, )} columns={procedureMetricsColumns} @@ -106,6 +121,14 @@ export function ProcedureMetricsDisplay(props: { manualSorting: false, initialSorting, }} + rowNavRoute={(row) => + taskMetricsEnabled + ? routes.metrics.details( + row.original.businessModule, + row.original.procedureType, + ) + : undefined + } /> </TableSheet> </Stack> diff --git a/employee-portal/src/lib/baseModule/components/procedureMetrics/columns.tsx b/employee-portal/src/lib/baseModule/components/procedureMetrics/columns.tsx index 98bbedd90e2a0aea88f099e60a70062785e2595b..05384f70d7a73895f936ecd11963c456b9cf2307 100644 --- a/employee-portal/src/lib/baseModule/components/procedureMetrics/columns.tsx +++ b/employee-portal/src/lib/baseModule/components/procedureMetrics/columns.tsx @@ -23,25 +23,38 @@ export const columnName = { const columnHelper = createColumnHelper<ApiProcedureMetric>(); +const meta = { + canNavigate: { + parentRow: true, + }, + width: "6rem", +}; + export const procedureMetricsColumns = [ columnHelper.accessor("procedureType", { header: columnName.procedureType, cell: (props) => procedureTypeNames[props.getValue()], + meta, }), columnHelper.accessor("totalCount", { header: columnName.totalCount, + meta, }), columnHelper.accessor("openOrDraftCount", { header: columnName.openOrDraftCount, + meta, }), columnHelper.accessor("inProgressCount", { header: columnName.inProgressCount, + meta, }), columnHelper.accessor("closedCount", { header: columnName.closedCount, + meta, }), columnHelper.accessor("abortedCount", { header: columnName.abortedCount, + meta, }), columnHelper.accessor("averageDuration", { header: columnName.averageDuration, @@ -49,6 +62,7 @@ export const procedureMetricsColumns = [ const value = props.getValue(); return isDefined(value) ? formatDurationRounded(value) : "-"; }, + meta, }), ]; diff --git a/employee-portal/src/lib/baseModule/components/releaseNotes/ReleaseNotes.tsx b/employee-portal/src/lib/baseModule/components/releaseNotes/ReleaseNotes.tsx index f021171ad909bfddf43f3c4be2c98a7244b3144f..dd1c0e82e4044d4821169a529bf8c70720f8efb1 100644 --- a/employee-portal/src/lib/baseModule/components/releaseNotes/ReleaseNotes.tsx +++ b/employee-portal/src/lib/baseModule/components/releaseNotes/ReleaseNotes.tsx @@ -5,7 +5,7 @@ import { Divider, List, ListItem, Stack, Typography } from "@mui/joy"; -import { ContentPanel } from "@/lib/shared/components/contentPanel/ContentPanel"; +import { StaticTextDocumentPanel } from "@/lib/baseModule/components/StaticTextDocumentPanel"; function BulletPointPlain(props: { text: string }) { return ( @@ -27,13 +27,21 @@ function Module(props: { moduleName: string }) { export function ReleaseNotes() { return ( - <ContentPanel> + <StaticTextDocumentPanel> <Stack gap={2}> - <Typography level="h2">ESHG 1.0</Typography> + <Typography level="h2">GA-Lotse 1.0</Typography> <Divider /> - <Typography level="title-md">15.08.2024</Typography> + <Typography level="title-md">26.09.2024</Typography> <Typography level="body-md"> - Erster Release der neuen Anwendung für Gesundheitsämter. + Erster Release der neuen Anwendung GA-Lotse für Gesundheitsämter. + <br /> + <br /> + GA-Lotse ist ein Kooperationsprojekt des Gesundheitsamt Frankfurt am + Main mit dem Hessisches Ministerium für Familie, Senioren, Sport, + Gesundheit und Pflege. + <br /> + <br /> + Finanziert von der Europäischen Union – NextGenerationEU </Typography> </Stack> <Stack> @@ -250,6 +258,6 @@ export function ReleaseNotes() { </ListItem> </List> </Stack> - </ContentPanel> + </StaticTextDocumentPanel> ); } diff --git a/employee-portal/src/lib/baseModule/components/task/Teamview.tsx b/employee-portal/src/lib/baseModule/components/task/Teamview.tsx index 8048d0aed56b5e9a5299d8f95ae602bf06767742..00c2feb08f0fcf6e57e8a461b0cdb84016732b89 100644 --- a/employee-portal/src/lib/baseModule/components/task/Teamview.tsx +++ b/employee-portal/src/lib/baseModule/components/task/Teamview.tsx @@ -11,11 +11,11 @@ import { ApiTask, ApiUser, } from "@eshg/employee-portal-api/businessProcedures"; -import { UseSuspenseQueryResult } from "@tanstack/react-query"; +import { UseQueryOptions, useSuspenseQueries } from "@tanstack/react-query"; import { differenceInDays } from "date-fns"; import { useState } from "react"; -import { useGetUsersByGroupQuery } from "@/lib/baseModule/api/queries/users"; +import { useGetUsersByGroupQueryOptions } from "@/lib/baseModule/api/queries/users"; import { teamviewColumns } from "@/lib/baseModule/components/task/teamviewColumns"; import { useTeamviewFilterSettings } from "@/lib/baseModule/components/task/useTeamviewFilterSettings"; import { resolveProcedureDetailsRoute } from "@/lib/baseModule/moduleRegister/routeResolver"; @@ -53,17 +53,28 @@ function memberFilter({ assigneeId }: TeamviewFilters) { interface TeamviewPageProps { groupName: string; businessModule: ApiBusinessModule; - useFetchTasksForTeamView: ( + useFetchTasksForTeamViewOptions: ( teamviewFilters: TeamviewFilters, - ) => UseSuspenseQueryResult<ApiGetTaskByUserResponse, Error>; + ) => UseQueryOptions< + ApiGetTaskByUserResponse, + Error, + ApiGetTaskByUserResponse, + readonly (string | string[] | Record<string, string>)[] + >; } export function Teamview(props: Readonly<TeamviewPageProps>) { - const groupMembers = useGetUsersByGroupQuery(props.groupName).data.users; - const [filters, setFilters] = useState<TeamviewFilters>({}); - const { data: taskResponse } = props.useFetchTasksForTeamView(filters); + const [{ data: groupMemberResponse }, { data: taskResponse }] = + useSuspenseQueries({ + queries: [ + useGetUsersByGroupQueryOptions(props.groupName), + props.useFetchTasksForTeamViewOptions(filters), + ], + }); + + const groupMembers = groupMemberResponse.users; function toTaskRows(groupMember: ApiUser): TaskRow { const tasks = taskResponse.tasksByUser[groupMember.userId] ?? []; diff --git a/employee-portal/src/lib/baseModule/components/usage/UsageNotes.tsx b/employee-portal/src/lib/baseModule/components/usage/UsageNotes.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c8d8b40cc46ac65c857ef2fc4296228933d3e146 --- /dev/null +++ b/employee-portal/src/lib/baseModule/components/usage/UsageNotes.tsx @@ -0,0 +1,218 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Stack, Typography } from "@mui/joy"; +import { PropsWithChildren } from "react"; + +import { + LinkInNewTab, + StaticTextDocumentPanel, +} from "@/lib/baseModule/components/StaticTextDocumentPanel"; + +function Section({ + id, + title, + children, +}: PropsWithChildren<{ id: string; title: string }>) { + return ( + <Stack component={"section"} aria-labelledby={id} gap={1}> + <Typography level={"h2"} id={id}> + {title} + </Typography> + {children} + </Stack> + ); +} + +export function UsageNotes() { + return ( + <StaticTextDocumentPanel> + <Section + id={"general-recommendations"} + title={"Generelle Empfehlungen zur Nutzung"} + > + <Typography> + Wir empfehlen die Beachtung der folgenden Hinweise zur sicheren + Benutzung des Online-Portals. + </Typography> + <Stack component={"ol"} gap={1}> + <li> + <Typography level={"title-md"}> + Aktuellen Browser und Betriebssystem verwenden + </Typography> + <Typography> + Um eine optimale Nutzung und Sicherheit zu gewährleisten, + empfehlen wir die Nutzung eines möglichst aktuellen Browsers und + Betriebssystems. Das Online-Portal wurde mit den gängigsten + Browsern (Google Chrome, Mozilla Firefox, Microsoft Edge, Apple + Safari) auf unterschiedlichen Plattformen (Desktop, Mobile, + Smartphone) getestet. Regelmäßige Updates schützen vor + Sicherheitslücken und stellen sicher, dass die Anwendung korrekt + funktioniert. + </Typography> + </li> + <li> + <Typography level={"title-md"}> + Gerät bei Nichtbenutzung sperren + </Typography> + <Typography> + Stellen Sie sicher, dass Ihr Computer, Smartphone oder Tablet bei + Nichtbenutzung immer gesperrt ist. Dies schützt Ihre Daten vor + unbefugtem Zugriff, falls Sie Ihr Gerät unbeaufsichtigt lassen. + </Typography> + </li> + <li> + <Typography level={"title-md"}> + Browser nach der Nutzung der Anwendung schließen + </Typography> + <Typography> + Um Ihre Privatsphäre zu schützen, schließen Sie nach der Nutzung + der Anwendung Ihren Browser. So verhindern Sie, dass sensible + Daten im Zwischenspeichers Ihres Geräts gespeichert bleiben. + </Typography> + </li> + </Stack> + <Typography> + Weitere Hinweise zur sicheren Nutzung finden Sie auf den{" "} + <LinkInNewTab + href={ + "https://www.bsi.bund.de/DE/Themen/Verbraucherinnen-und-Verbraucher/Informationen-und-Empfehlungen/Cyber-Sicherheitsempfehlungen/cyber-sicherheitsempfehlungen_node.html" + } + > + Webseiten + </LinkInNewTab>{" "} + des Bundesamts für Sicherheit in der Informationstechnik (BSI). + </Typography> + </Section> + + <Section + id={"passkey-passwordless-logins"} + title={"Hinweise zur Nutzung von Passkeys und passwortloser Anmeldung"} + > + <Typography> + Zur sicheren Anmeldung am Mitarbeitenden-Portal und Admin-Funktionen + des Mitarbeitenden-Portals verwendet GA-Lotse passwortlose + Anmeldeverfahren mittels Passkeys. + <br /> + <br /> + Bei diesen Verfahren werden zu jeder Anmeldung keine Passwörter + übermittelt, sondern für jede Anmeldung mittels eines kryptografischen + Verfahren individuell berechnete Antworten auf kryptografische Fragen. + <br /> + Da bei der Anmeldung mittels Passkeys bei jeder Anmeldung eine neue + Antwort berechnet wird, besteht keine Möglichkeit mehr zum Abgreifen + von Passwörtern mittels Phishing. Darüber hinaus sind Passkeys an eine + bestimmte Domain gebunden und können nur auf dieser verwendet werden. + </Typography> + </Section> + + <Section + id={"passkey-usage-possibilities"} + title={"Möglichkeiten der Nutzung von Passkeys"} + > + <Typography> + Bei der Nutzung von Passkeys sind verschiedene Optionen möglich. + <br /> + Vor der Nutzung eines Passkeys muss ein Passkey registriert werden. + <br /> + Für Mitarbeitende im Mitarbeitendenportal kann immer nur ein Passkey + pro User registriert werden. + <br /> + Für die Admin-Funktion ist es möglich, mehrere Passkeys pro User zu + hinterlegen. Es wird für die Admin-Funktion ausdrücklich empfohlen, + mehr als einen Passkey zu registrieren. Im Falle eines Verlustes kann + so das Aussperren von dem Admin-Funktionen verhindert werden. + </Typography> + </Section> + + <Section + id={"different-devices-and-logins"} + title={"Unterschiedliche Arten von Geräten und Anmeldungen"} + > + <Typography> + Zur Nutzung von Passkeys werden die Möglichkeiten mittels FIDO-Token + (USB-Stick) oder Smartphone (iOS 16+, Android 9+) empfohlen. + <br /> + Bei der Anmeldung bei GA-Lotse mittels Passkeys ist immer ein zweiter + Faktor notwendig. Das kann je nach Möglichkeiten des Gerätes eine PIN + oder die Authentifizierung via Biometrie (Fingerabdruck oder FaceID) + sein. + <br /> + Für die Nutzung der Admin-Funktion ist zusätzlich ein Username und + Passwort notwendig. Admin-Funktion und Mitarbeitendenportal verwenden + unterschiedliche Passkeys. Diese lassen sich aber auf dem gleichen + Stick oder Smartphone speichern. + </Typography> + </Section> + + <Section + id={"passkey-registration"} + title={"Registrierung eines Passkeys"} + > + <Typography> + Zur Registrierung eines Passkeys erhalten Sie eine E-Mail. Nach Klick + auf den entsprechenden Registrierungslink können Sie ihren Passkeys + registrieren. + <br /> + <br /> + Bei der Registrierung eines Passkeys an GA-Lotse muss ein PIN oder + eine andere Art von zweitem Faktor hinterlegt werden. + </Typography> + </Section> + + <Section + id={"hardware-passkey-usage"} + title={"Nutzung von Passkeys mittels Hardware-Token"} + > + <Typography> + Passkeys können via USB-Stick mittels FIDO Standard genutzt werden. + Zur Nutzung wird der Stick an jeweiligen Rechner angesteckt oder via + NFC mit einem Smartphone verbunden. + <br /> + Nach dem Verbinden muss eine PIN eingegeben werden. + <br /> + <br /> + Bei der Nutzung eines Tokens per USB-Verbindung muss oftmals der Stick + an einer bestimmten Stelle berührt werden, um einen kapazitiven + Kontakt herzustellen. + </Typography> + </Section> + + <Section + id={"smartphone-passkeys"} + title={"Nutzung von Passkeys mittels Smartphone"} + > + <Typography> + Zur Nutzung von Passkeys mittels Smartphone kann entweder der Passkey + direkt auf dem Smartphone genutzt werden. + <br /> + Alternativ kann zur Anmeldung auch ein QR-Code gescannt werden, um + dann via Bluetooth den Passkey zur Anmeldung zu übertragen. + </Typography> + </Section> + + <Section + id={"lost-passkey-protocol"} + title={"Umgang mit Verlust eines Passkeys"} + > + <Typography> + Bei Verlust eines Passkeys kann der jeweilige Passkey im Admin-Portal + deaktiviert werden. Der Verlust eines Passkeys ist daher unverzüglich + zu melden. + </Typography> + </Section> + + <Section + id={"passkey-synchronization"} + title={"Synchronisation von Passkeys"} + > + <Typography> + Es wird nicht empfohlen, Passkeys über Dienste von Dritten (iCloud, + Google Dienste) zu synchronisieren. + </Typography> + </Section> + </StaticTextDocumentPanel> + ); +} diff --git a/employee-portal/src/lib/baseModule/moduleRegister/sideNavigationItemsResolver.tsx b/employee-portal/src/lib/baseModule/moduleRegister/sideNavigationItemsResolver.tsx index 7851fadb50ad9ae6954461593e13575aead1222e..51ca9f949c4f5fed3ffde8268b91bb8eea9cec62 100644 --- a/employee-portal/src/lib/baseModule/moduleRegister/sideNavigationItemsResolver.tsx +++ b/employee-portal/src/lib/baseModule/moduleRegister/sideNavigationItemsResolver.tsx @@ -12,6 +12,7 @@ import { useSideNavigationItems as useSchoolEntrySideNavigationItems } from "@/l import { useSideNavigationItems as useStatisticsSideNavigationItems } from "@/lib/businessModules/statistics/shared/sideNavigationItem"; import { useSideNavigationItems as useStiProtectionSideNavigationItems } from "@/lib/businessModules/stiProtection/shared/sideNavigationItem"; import { useSideNavigationItems as useTravelMedicineSideNavigationItems } from "@/lib/businessModules/travelMedicine/shared/sideNavigationItem"; +import { sideNavigationItems as archivingSideNavigationItems } from "@/lib/shared/components/archiving/shared/sideNavigationItem"; export function useResolveSideNavigationItems(): SideNavigationItem[] { const inspectionSideNavigationItems = useInspectionSideNavigationItems(); @@ -33,6 +34,7 @@ export function useResolveSideNavigationItems(): SideNavigationItem[] { ...measlesProtectionSideNavigationItems, ...stiProtectionSideNavigationItems, ...statisticsSideNavigationItems, + ...archivingSideNavigationItems, ...chatSideNavigationItems, ]; return [...baseSideNavigationItems, ...businessModuleSideNavigationItems]; diff --git a/employee-portal/src/lib/baseModule/shared/routes.ts b/employee-portal/src/lib/baseModule/shared/routes.ts index cd0f14b54f05ef77ca569e02ec31e0b03526f751..0258bd4a512f7857c2c7ec1666aba3aee94ee539 100644 --- a/employee-portal/src/lib/baseModule/shared/routes.ts +++ b/employee-portal/src/lib/baseModule/shared/routes.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { ApiProcedureType } from "@eshg/employee-portal-api/base"; import { isDefined } from "remeda"; const accountPath = "/account"; @@ -14,12 +15,14 @@ const contactsPath = "/contacts"; const resourcesPath = "/resources"; const inventoryPath = "/inventory"; const usersPath = "/users"; - +const metricsPath = "/metrics"; const gdprPath = "/gdpr"; + export const routes = { index: "/", account: { sessions: `${accountPath}/sessions`, + loginProtocol: `${accountPath}/login-protocol`, }, procedures: { index: proceduresPath, @@ -50,7 +53,11 @@ export const routes = { index: usersPath, details: (userId: string) => `${usersPath}/${userId}`, }, - metrics: "/metrics", + metrics: { + index: metricsPath, + details: (businessModuleName: string, procedureType: ApiProcedureType) => + `${metricsPath}/${businessModuleName}/${procedureType}`, + }, auditlog: { index: auditLogPath, authorize: { @@ -67,4 +74,5 @@ export const routes = { privacy: "/privacy", accessibility: "/accessibility", contact: "/contact", + usageNotes: "/usage-notes", } as const; diff --git a/employee-portal/src/lib/baseModule/sideNavigationItems.tsx b/employee-portal/src/lib/baseModule/sideNavigationItems.tsx index 218112ab898dbd684357ce35a1fb10d1bd86e13b..23dbc51424df2e750e6623978c3db8e780118b16 100644 --- a/employee-portal/src/lib/baseModule/sideNavigationItems.tsx +++ b/employee-portal/src/lib/baseModule/sideNavigationItems.tsx @@ -72,7 +72,7 @@ const sideNavigationItems: SideNavigationItem[] = [ }, { name: "Kennzahlen", - href: routes.metrics, + href: routes.metrics.index, decorator: <Speed />, accessCheck: hasUserRole(ApiUserRole.BaseProcedureMetricsRead), }, diff --git a/employee-portal/src/lib/businessModules/chat/components/BadgeAvatar.tsx b/employee-portal/src/lib/businessModules/chat/components/BadgeAvatar.tsx deleted file mode 100644 index 987cda8f42ca03670e715e9085051aae7466c0c3..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/BadgeAvatar.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { RequiresChildren } from "@eshg/lib-portal/types/react"; -import { Badge, Box } from "@mui/joy"; - -import { Presence } from "@/lib/businessModules/chat/shared/types"; - -export interface BadgeAvatarProps extends RequiresChildren { - status: Presence | undefined; -} - -export function BadgeAvatar({ status, children }: Readonly<BadgeAvatarProps>) { - return ( - <Box sx={{ display: "flex", gap: 2, alignItems: "center" }}> - <Badge - anchorOrigin={{ vertical: "bottom", horizontal: "right" }} - badgeInset="18%" - color={getColor(status)} - variant="solid" - size="sm" - invisible={!status} - > - {children} - </Badge> - </Box> - ); -} - -function getColor(status: Presence | undefined) { - if (status === undefined) { - return; - } - if (status === "online") { - return "success"; - } - if (status === "offline") { - return "danger"; - } - if (status === "unavailable") { - return "neutral"; - } -} diff --git a/employee-portal/src/lib/businessModules/chat/components/Chat.tsx b/employee-portal/src/lib/businessModules/chat/components/Chat.tsx index 9c913282f17b075124dfa4f579e266cf5a0f6473..eefbf5165ee20e2ba499ab64a37ceceb15530e9b 100644 --- a/employee-portal/src/lib/businessModules/chat/components/Chat.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/Chat.tsx @@ -6,28 +6,36 @@ "use client"; import { LoadingIndicator } from "@eshg/lib-portal/components/LoadingIndicator"; -import { Box, Stack, useTheme } from "@mui/joy"; +import { Stack, useTheme } from "@mui/joy"; import { useSearchParams } from "next/navigation"; import { useEffect, useState } from "react"; -import { NewChatIllustration } from "@/lib/businessModules/chat/assets/NewChatIllustration"; -import { ChatColumnHeaderWrapper } from "@/lib/businessModules/chat/components/ChatColumnHeaderWrapper"; import { ChatPanel } from "@/lib/businessModules/chat/components/chatPanel/ChatPanel"; import { RoomsPanel } from "@/lib/businessModules/chat/components/roomsPanel/RoomsPanel"; import { BackupSetupView } from "@/lib/businessModules/chat/components/secureBackup/BackupSetupView"; +import { SettingsPanel } from "@/lib/businessModules/chat/components/settingsPanel/SettingsPanel"; import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; -import { ClientState } from "@/lib/businessModules/chat/shared/enums"; +import { + ChatPanelView, + ClientState, +} from "@/lib/businessModules/chat/shared/enums"; import { useCreateNewChat } from "@/lib/businessModules/chat/shared/hooks/useCreateNewChat"; export function Chat() { const searchParams = useSearchParams(); const roomId = searchParams.get("roomId"); const userIdForChatStart = searchParams.get("userId"); - const theme = useTheme(); const { clientState } = useChatClientContext(); const { createNewDirectMessage } = useCreateNewChat(); const [openChatSettings, setOpenChatSettings] = useState(false); + const [chatPanelView, setChatPanelView] = useState<ChatPanelView>( + roomId ? ChatPanelView.ChatMessages : ChatPanelView.NoChatSelected, + ); + + function changeChatPanelView(newView: ChatPanelView) { + setChatPanelView(newView); + } function toggleChatSettingsView() { setOpenChatSettings((prev) => !prev); @@ -61,54 +69,64 @@ export function Chat() { return ( <Stack direction="row" - justifyContent="space-between" border={1} sx={{ height: "100%", - backgroundColor: theme.palette.background.surface, + justifyContent: "space-between", + backgroundColor: theme.palette.background.body, borderColor: theme.palette.neutral.outlinedBorder, borderRadius: theme.radius.lg, overflow: "hidden", }} > - <Box + <Stack sx={{ + flex: 1, + minWidth: "12.5rem", maxWidth: "27rem", height: "100%", + overflow: "auto", }} > - <RoomsPanel /> - </Box> - <Box + <RoomsPanel + setChatPanelView={changeChatPanelView} + isOpenChatSettings={openChatSettings} + toggleChatSettingsView={toggleChatSettingsView} + /> + </Stack> + <Stack sx={{ - flex: 2, + flex: 1.5, + minWidth: 0, borderLeft: "1px solid", borderColor: theme.palette.neutral.outlinedBorder, - overflow: "hidden", - minWidth: "50%", + overflow: "auto", }} > - {roomId ? ( - <ChatPanel - roomId={roomId} - isOpenChatSettings={openChatSettings} - toggleChatSettingsView={toggleChatSettingsView} - /> - ) : ( - <NewChatIllustration sx={{ width: "400px", height: "auto" }} /> - )} - </Box> - {openChatSettings && ( - <Box + <ChatPanel + roomId={roomId} + isOpenChatSettings={openChatSettings} + toggleChatSettingsView={toggleChatSettingsView} + chatPanelView={chatPanelView} + setChatPanelView={changeChatPanelView} + /> + </Stack> + {openChatSettings && roomId && ( + <Stack sx={{ flex: 1, + minWidth: 0, maxWidth: "22rem", borderLeft: "1px solid", - borderColor: theme.palette.neutral.outlinedBorder, + borderColor: "neutral.outlinedBorder", }} > - <ChatColumnHeaderWrapper>Chat details</ChatColumnHeaderWrapper> - </Box> + <SettingsPanel + roomId={roomId} + isOpenChatSettings={openChatSettings} + toggleChatSettingsView={toggleChatSettingsView} + /> + </Stack> )} </Stack> ); diff --git a/employee-portal/src/lib/businessModules/chat/components/ChatAvatar.tsx b/employee-portal/src/lib/businessModules/chat/components/ChatAvatar.tsx index 16e40c36f128573e6c048349cb526a02e1fcc8ef..31320dd24257fe2087e893a2285e2c0f07acf226 100644 --- a/employee-portal/src/lib/businessModules/chat/components/ChatAvatar.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/ChatAvatar.tsx @@ -6,49 +6,64 @@ import GroupOutlinedIcon from "@mui/icons-material/GroupOutlined"; import { Avatar, Badge } from "@mui/joy"; +import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; import { Presence } from "@/lib/businessModules/chat/shared/types"; import { getInitials, getStatusColor, + isGroupRoom, stringToColor, } from "@/lib/businessModules/chat/shared/utils"; interface ChatAvatarProps { + userId?: string; name?: string; - avatarUrl?: string; - presence?: Presence; + avatarUrl: string | null; communicationType?: CommunicationType; size?: "sm" | "md" | "lg"; + disablePresence?: boolean; } +type BadgeAvatarProps = { + presence?: Presence; +} & Omit<ChatAvatarProps, "communicationType">; + export function ChatAvatar({ communicationType = CommunicationType.DirectMessage, size = "md", + userId, ...props }: ChatAvatarProps) { - return communicationType === CommunicationType.PublicRoom ? ( + const { usersPresence } = useChatClientContext(); + + const { + userSettings: { sharePresence }, + } = useChat(); + + return isGroupRoom(communicationType) ? ( <Avatar variant="solid" color="warning" size={size}> <GroupOutlinedIcon size="md" sx={{ color: "white" }} /> </Avatar> ) : ( - <BadgeAvatar size={size} {...props} /> + <BadgeAvatar + size={size} + presence={sharePresence ? usersPresence[userId ?? ""] : undefined} + {...props} + /> ); } function BadgeAvatar({ - presence, avatarUrl, name, size, -}: Omit<ChatAvatarProps, "communicationType">) { - const { - userSettings: { sharePresence }, - } = useChat(); - + disablePresence = false, + presence, +}: BadgeAvatarProps) { const content = getInitials(name); - const invisiblePresence = !sharePresence || !presence; + const invisiblePresence = disablePresence || !presence; return ( <Badge @@ -66,7 +81,7 @@ function BadgeAvatar({ <Avatar variant="solid" color={stringToColor(name)} - src={avatarUrl} + src={avatarUrl ?? ""} size={size} sx={{ fontWeight: 500, diff --git a/employee-portal/src/lib/businessModules/chat/components/ChatColumnHeaderWrapper.tsx b/employee-portal/src/lib/businessModules/chat/components/ChatColumnHeaderWrapper.tsx index c27a277d15a34907da0e3657b73dc210b93f811f..e1e3fa0ff4afbae3d83e30e411a5a2d181459e90 100644 --- a/employee-portal/src/lib/businessModules/chat/components/ChatColumnHeaderWrapper.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/ChatColumnHeaderWrapper.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { Stack, useTheme } from "@mui/joy"; +import { Stack } from "@mui/joy"; import { ReactNode } from "react"; export const chatColumnHeaderHeight = "5.25rem"; @@ -13,15 +13,15 @@ export function ChatColumnHeaderWrapper({ }: { children?: ReactNode; }) { - const theme = useTheme(); return ( <Stack justifyContent="center" sx={{ height: chatColumnHeaderHeight, borderBottom: "1px solid", - borderColor: theme.palette.neutral.outlinedBorder, - paddingX: theme.spacing(3), + borderColor: "neutral.outlinedBorder", + paddingX: 3, + flexShrink: 0, }} > {children} diff --git a/employee-portal/src/lib/businessModules/chat/components/ChatHeader.tsx b/employee-portal/src/lib/businessModules/chat/components/ChatHeader.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a6c24d78c45bde51c07a3f62d6e388f9f39e4055 --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/ChatHeader.tsx @@ -0,0 +1,93 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import NotificationsOffOutlinedIcon from "@mui/icons-material/NotificationsOffOutlined"; +import { Stack, Typography, useTheme } from "@mui/joy"; + +import { ChatAvatar } from "@/lib/businessModules/chat/components/ChatAvatar"; +import { OnlineStatus } from "@/lib/businessModules/chat/components/OnlineStatus"; +import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; +import { RoomInfo } from "@/lib/businessModules/chat/shared/hooks/useRoomInfo"; +import { getDepartmentNameFromUserId } from "@/lib/businessModules/chat/shared/utils"; + +export interface ChatHeaderProps extends RoomInfo { + variant?: "default" | "settings"; +} + +export function ChatHeader({ + roomAvatarUrl, + communicationType, + dmRoomMember, + room, + roomMembers, + variant = "default", +}: ChatHeaderProps) { + const theme = useTheme(); + const isSettings = variant === "settings"; + + // TO DO - finish mute feature + const muteIndicator = false; + + return ( + <Stack + direction="row" + spacing={2} + sx={{ + alignItems: "center", + width: "100%", + minWidth: 0, + }} + > + <ChatAvatar + name={room?.name} + communicationType={communicationType} + avatarUrl={roomAvatarUrl} + size="lg" + userId={dmRoomMember?.member.userId} + disablePresence={!isSettings} + /> + <Stack sx={{ flex: 1, overflow: "hidden" }}> + <Stack direction="row" spacing={0.5} sx={{ alignItems: "center" }}> + <Typography + noWrap + level={variant === "settings" ? "title-md" : "h3"} + sx={{ minWidth: "5ch" }} + > + {room?.name} + </Typography> + {muteIndicator && ( + <NotificationsOffOutlinedIcon + sx={{ + width: "1.125rem", + height: "1.125rem", + color: theme.palette.neutral.outlinedDisabledColor, + }} + /> + )} + </Stack> + {variant === "default" && ( + <Stack direction="row" spacing={2}> + {roomMembers?.map((item) => ( + <OnlineStatus + key={item.member.userId} + userId={item.member.userId} + name={roomMembers.length > 1 ? item.member.name : undefined} + /> + ))} + </Stack> + )} + {variant === "settings" && + communicationType === CommunicationType.DirectMessage && ( + <Typography noWrap sx={{ minWidth: "5ch" }}> + { + getDepartmentNameFromUserId(dmRoomMember?.member.userId) + ?.username + } + </Typography> + )} + </Stack> + </Stack> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/ChatIllustrationBackground.tsx b/employee-portal/src/lib/businessModules/chat/components/ChatIllustrationBackground.tsx new file mode 100644 index 0000000000000000000000000000000000000000..31e208df8b9e0ca5860b2b7e0d2dc4ad1955c4de --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/ChatIllustrationBackground.tsx @@ -0,0 +1,27 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Box } from "@mui/joy"; + +import { NewChatIllustration } from "@/lib/businessModules/chat/assets/NewChatIllustration"; + +export function ChatIllustrationBackground() { + return ( + <Box + sx={{ + width: "100%", + height: "100%", + display: "flex", + justifyContent: "center", + alignItems: "center", + overflow: "auto", + }} + > + <NewChatIllustration + sx={{ width: "100%", height: "100%", maxWidth: "27.5rem" }} + /> + </Box> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/ChatInputField.tsx b/employee-portal/src/lib/businessModules/chat/components/ChatInputField.tsx new file mode 100644 index 0000000000000000000000000000000000000000..29a5bb3ad4180b6693bfa787eebe80fafebcdbf6 --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/ChatInputField.tsx @@ -0,0 +1,112 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useIsFormDisabled } from "@eshg/lib-portal/components/form/DisabledFormContext"; +import { + BaseField, + FieldComponentProps, + useBaseField, +} from "@eshg/lib-portal/components/formFields/BaseField"; +import { StyledInputProps } from "@eshg/lib-portal/components/formFields/types"; +import { FieldProps } from "@eshg/lib-portal/types/form"; +import { Input, InputProps } from "@mui/joy"; +import { SxProps } from "@mui/joy/styles/types"; +import { + ChangeEvent, + FocusEvent, + FocusEventHandler, + HTMLInputTypeAttribute, + ReactNode, +} from "react"; + +export interface ChatInputFieldProps + extends FieldProps<string>, + FieldComponentProps, + StyledInputProps { + type?: HTMLInputTypeAttribute; + placeholder?: string; + unstyledReadOnly?: boolean; + disabled?: boolean; + startDecorator?: ReactNode; + endDecorator?: ReactNode; + input?: (props: InputProps) => ReactNode; + onChange?: (newValue: string) => void; + onFocus?: FocusEventHandler<HTMLInputElement>; + onBlur?: FocusEventHandler<HTMLInputElement>; + onClick?: () => void; + sx?: SxProps; + "data-testid"?: string; + maxLength?: number; + "aria-label"?: string; + untrimmedInput?: boolean; +} + +export function ChatInputField(props: Readonly<ChatInputFieldProps>) { + const FieldComponent = props.component ?? BaseField; + const InputComponent = props.input ?? Input; + const field = useBaseField<string>(props); + const disabled = useIsFormDisabled(); + + function handleChange(event: ChangeEvent<HTMLInputElement>): void { + field.input.onChange(event); + props.onChange?.(event.target.value); + } + + async function handleBlur(event: FocusEvent<HTMLInputElement>) { + if (!props.untrimmedInput) { + const value = field.input.value; + const trimmedValue = value.trim(); + if (value !== trimmedValue) { + await field.helpers.setValue(trimmedValue); + event.target.value = trimmedValue; + } + } + field.input.onBlur?.(event); + props.onBlur?.(event); + } + + return ( + <FieldComponent + label={props.label} + helperText={field.helperText} + required={field.required} + error={field.error} + sx={props.sx} + fieldDecorator={props.fieldDecorator} + disabled={props.disabled ?? disabled} + > + <InputComponent + type={props.type} + name={props.name} + value={field.input.value} + placeholder={props.placeholder} + onChange={handleChange} + onFocus={props.onFocus} + onBlur={handleBlur} + onClick={props.onClick} + startDecorator={props.startDecorator} + endDecorator={props.endDecorator} + color={props.primary ? "primary" : undefined} + data-testid={props["data-testid"]} + aria-label={props["aria-label"]} + size="lg" + sx={{ + backgroundColor: "background.surface", + borderColor: "primary.300", + }} + slotProps={{ + input: { + maxLength: props.maxLength, + sx: { + "&::placeholder": { + color: "primary.300", + }, + }, + }, + }} + /> + </FieldComponent> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/ChatList.tsx b/employee-portal/src/lib/businessModules/chat/components/ChatList.tsx deleted file mode 100644 index c02c94664eb9d3a7221cc8d524267bd6d9666e15..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/ChatList.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; -import { Button, List, Stack } from "@mui/joy"; - -import { ChatListItem } from "@/lib/businessModules/chat/components/ChatListItem"; -import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; -import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; -import { useChatUtils } from "@/lib/businessModules/chat/shared/hooks/useChatUtils"; -import { useSelectedRoomId } from "@/lib/businessModules/chat/shared/hooks/useSelectedRoomId"; -import { RoomWithCommunicationType } from "@/lib/businessModules/chat/shared/types"; -import { getDirectMessageMember } from "@/lib/businessModules/chat/shared/utils"; - -interface ChatList { - handleAddChat: () => void; - buttonLabel: string; - roomList: RoomWithCommunicationType[]; - handleInvite?: (roomId: string) => Promise<void>; - handleSettings?: (roomId: string) => void; -} - -export function ChatList({ - handleAddChat, - buttonLabel, - roomList, - handleInvite, - handleSettings, -}: Readonly<ChatList>) { - const { - userSettings: { sharePresence }, - } = useChat(); - const { matrixClient, unreadNotificationsPerRoom, usersPresence } = - useChatClientContext(); - const { leaveRoom, getRoomAvatar } = useChatUtils(); - const { setSelectedRoomId, selectedRoomId } = useSelectedRoomId(); - - const loggedInUserId = matrixClient.getUserId(); - - return ( - <> - <Button - onClick={handleAddChat} - endDecorator={<AddCircleOutlineIcon />} - variant="plain" - color="primary" - fullWidth - sx={{ - display: "flex", - justifyContent: "space-between", - borderRadius: 0, - marginY: 1, - "&:hover": { backgroundColor: "transparent" }, - }} - > - {buttonLabel} - </Button> - <Stack - sx={{ - overflowY: "auto", - padding: 0, - borderRadius: 0, - maxWidth: { sm: "18rem", md: "24rem", lg: "26rem" }, - }} - > - <List sx={{ py: 0 }}> - {roomList.map((room) => { - const userId = getDirectMessageMember(room)?.userId; - const presenceStatus = - sharePresence && userId ? usersPresence[userId] : undefined; - const chatAdmin = room.room.getCreator(); - - return ( - <ChatListItem - key={room.room.roomId} - id={room.room.roomId} - roomName={room.room.name} - communicationType={room.communicationType} - leaveRoom={leaveRoom} - setSelectedRoomId={setSelectedRoomId} - selectedRoomId={selectedRoomId} - avatarUrl={getRoomAvatar(room)} - presence={presenceStatus} - handleInvite={handleInvite} - unreadNotifications={ - unreadNotificationsPerRoom[room.room.roomId] ?? 0 - } - isChatAdmin={chatAdmin === loggedInUserId} - handleSettings={handleSettings} - /> - ); - })} - </List> - </Stack> - </> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/ChatListItem.tsx b/employee-portal/src/lib/businessModules/chat/components/ChatListItem.tsx deleted file mode 100644 index 45f8caa9a9ea82f4eec024aa32150f65149b841c..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/ChatListItem.tsx +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import MoreHorizRoundedIcon from "@mui/icons-material/MoreHorizRounded"; -import { - Avatar, - Box, - Divider, - Dropdown, - IconButton, - ListItem, - ListItemButton, - Menu, - MenuButton, - MenuItem, - Typography, -} from "@mui/joy"; - -import { BadgeAvatar } from "@/lib/businessModules/chat/components/BadgeAvatar"; -import { ChatListItemAvatar } from "@/lib/businessModules/chat/components/ChatListItemAvatar"; -import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; -import { Presence } from "@/lib/businessModules/chat/shared/types"; - -export interface ChatListItemProps { - id: string; - roomName: string; - selectedRoomId: string | undefined; - setSelectedRoomId: (roomId: string) => void; - leaveRoom: (roomId: string) => Promise<void>; - communicationType: CommunicationType; - avatarUrl: string | undefined; - presence?: Presence; - handleInvite?: (roomId: string) => Promise<void>; - handleSettings?: (roomId: string) => void; - unreadNotifications: number; - isChatAdmin?: boolean; -} - -export function ChatListItem({ - id, - roomName, - selectedRoomId, - setSelectedRoomId, - leaveRoom, - communicationType, - avatarUrl, - presence, - handleInvite, - handleSettings, - unreadNotifications, - isChatAdmin, -}: Readonly<ChatListItemProps>) { - const selected = selectedRoomId === id; - - return ( - <ListItem sx={{ position: "relative" }}> - <ListItemButton - onClick={() => { - setSelectedRoomId(id); - }} - selected={selected} - color="neutral" - sx={{ py: 1, width: "100%" }} - > - <BadgeAvatar status={presence}> - <ChatListItemAvatar - avatarUrl={avatarUrl} - communicationType={communicationType} - sx={{ - width: { sm: "1rem", md: "2rem" }, - height: { sm: "1rem", md: "2rem" }, - }} - /> - </BadgeAvatar> - <Box - sx={{ - flex: 1, - display: "flex", - alignItems: "center", - justifyContent: "space-between", - }} - > - <Typography - level="body-md" - sx={{ - ...(unreadNotifications > 0 && { - textShadow: (theme) => - `0px 0px 1px ${theme.palette.text.primary}`, - }), - textOverflow: "ellipsis", - whiteSpace: "nowrap", - maxWidth: { sm: "6rem", md: "10rem", lg: "16rem" }, - overflow: "hidden", - }} - > - {roomName} - </Typography> - {unreadNotifications > 0 && ( - <Avatar - variant="solid" - color="danger" - sx={{ - marginRight: "calc(var(--IconButton-size, 2rem) + 0.5rem)", - width: "1.25rem", - height: "1.25rem", - fontSize: "0.625rem", - ml: 1, - fontWeight: "500", - }} - > - {unreadNotifications} - </Avatar> - )} - </Box> - </ListItemButton> - <Dropdown> - <MenuButton - slots={{ root: IconButton }} - slotProps={{ - root: { variant: "plain", color: "neutral", size: "sm" }, - }} - sx={{ position: "absolute", right: "var(--ListItem-paddingX)" }} - aria-label="Chatroom-Optionen" - > - <MoreHorizRoundedIcon /> - </MenuButton> - <Menu size="sm" sx={{ minWidth: 140 }}> - {communicationType === CommunicationType.PublicRoom && - isChatAdmin && ( - <> - <MenuItem onClick={() => handleInvite?.(id)}>Einladen</MenuItem> - <Divider /> - </> - )} - {communicationType === CommunicationType.PublicRoom && - isChatAdmin && ( - <> - <MenuItem onClick={() => handleSettings?.(id)}> - Chatroom-Einstellungen - </MenuItem> - <Divider /> - </> - )} - <MenuItem color="danger" onClick={() => leaveRoom(id)}> - Verlassen - </MenuItem> - </Menu> - </Dropdown> - </ListItem> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/ChatListItemAvatar.tsx b/employee-portal/src/lib/businessModules/chat/components/ChatListItemAvatar.tsx deleted file mode 100644 index 54ebcbc4e9252a464897f6e81cc447b4280a5bcd..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/ChatListItemAvatar.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import Groups2Icon from "@mui/icons-material/Groups2"; -import PersonOutlineIcon from "@mui/icons-material/PersonOutline"; -import { Avatar, AvatarProps } from "@mui/joy"; - -import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; - -interface ChatListItemAvatarProps extends AvatarProps { - avatarUrl: string | undefined; - communicationType: CommunicationType; -} - -export function ChatListItemAvatar({ - avatarUrl, - communicationType, - ...props -}: Readonly<ChatListItemAvatarProps>) { - if (avatarUrl) { - return <Avatar src={avatarUrl} variant="outlined" {...props} />; - } - return ( - <Avatar {...props}> - {communicationType === CommunicationType.PublicRoom ? ( - <Groups2Icon /> - ) : ( - <PersonOutlineIcon /> - )} - </Avatar> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/ChatSettingsModal.tsx b/employee-portal/src/lib/businessModules/chat/components/ChatSettingsModal.tsx deleted file mode 100644 index 58d626315696f55d9af1d6e5c0663d2041392fc2..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/ChatSettingsModal.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { SubmitButton } from "@eshg/lib-portal/components/buttons/SubmitButton"; -import { FormPlus } from "@eshg/lib-portal/components/form/FormPlus"; -import { Box, FormLabel, Radio, Sheet, Typography } from "@mui/joy"; -import { Formik } from "formik"; -import { HistoryVisibility } from "matrix-js-sdk/lib/matrix"; -import { isEmpty } from "remeda"; - -import { SettingsFormValues } from "@/lib/businessModules/chat/components/ChatsPane"; -import { ChatBaseModal } from "@/lib/businessModules/chat/shared/types"; -import { BaseModal } from "@/lib/shared/components/BaseModal"; -import { RadioGroupField } from "@/lib/shared/components/formFields/RadioGroupField"; - -const historyVisibilityOptions = [ - { - value: HistoryVisibility.Invited, - label: "Nur Mitglieder (seit sie eingeladen wurden)", - }, - { - value: HistoryVisibility.Joined, - label: "Nur Mitglieder (seit sie beigetreten sind)", - }, - { - value: HistoryVisibility.Shared, - label: "Nur Mitglieder (ab dem Zeitpunkt der Aktivierung dieser Option)", - }, -]; - -interface ChatSettingsModalProps extends ChatBaseModal<SettingsFormValues> { - initialFormValues: SettingsFormValues; -} - -export function ChatSettingsModal({ - open, - onClose, - onSubmit, - initialFormValues, - validateForm, -}: Readonly<ChatSettingsModalProps>) { - return ( - <BaseModal open={open} onClose={onClose} modalTitle="Chat-Einstellungen"> - <Sheet - variant="plain" - sx={{ - minHeight: "20rem", - }} - > - <Formik<SettingsFormValues> - initialValues={initialFormValues} - onSubmit={onSubmit} - validate={validateForm} - > - {({ isSubmitting, errors }) => ( - <FormPlus> - <FormLabel htmlFor="historyVisibility"> - Wer kann den Verlauf lesen? - </FormLabel> - <Typography level="body-xs"> - Änderungen bezüglich der Leseberechtigung für den Verlauf gelten - nur für zukünftige Nachrichten in diesem Chatroom. Die - Sichtbarkeit des bestehenden Verlaufs bleibt unverändert. - </Typography> - <RadioGroupField name="historyVisibility"> - {historyVisibilityOptions.map(({ label, value }) => ( - <Radio value={value} label={label} key={value} size="sm" /> - ))} - </RadioGroupField> - <Box marginTop={4}> - <SubmitButton - submitting={isSubmitting} - disabled={!isEmpty(errors)} - > - Speichern - </SubmitButton> - </Box> - </FormPlus> - )} - </Formik> - </Sheet> - </BaseModal> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/ChatsPane.tsx b/employee-portal/src/lib/businessModules/chat/components/ChatsPane.tsx deleted file mode 100644 index 49f1d51c25a61710d7ad1b22eae042eb5c3c4218..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/ChatsPane.tsx +++ /dev/null @@ -1,290 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -"use client"; - -import { AlertProps } from "@eshg/lib-portal/components/Alert"; -import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; -import { Sheet } from "@mui/joy"; -import { FormikErrors } from "formik"; -import { logger } from "matrix-js-sdk/lib/logger"; -import { HistoryVisibility } from "matrix-js-sdk/lib/matrix"; -import { useMemo, useState } from "react"; - -import { ChatList } from "@/lib/businessModules/chat/components/ChatList"; -import { ChatSettingsModal } from "@/lib/businessModules/chat/components/ChatSettingsModal"; -import { DirectMessageModal } from "@/lib/businessModules/chat/components/DirectMessageModal"; -import { GroupChatModal } from "@/lib/businessModules/chat/components/GroupChatModal"; -import { InviteToChatModal } from "@/lib/businessModules/chat/components/InviteToChatModal"; -import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; -import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; -import { useChatRoomList } from "@/lib/businessModules/chat/shared/hooks/useChatRoomList"; -import { useChatUtils } from "@/lib/businessModules/chat/shared/hooks/useChatUtils"; -import { useCreateNewChat } from "@/lib/businessModules/chat/shared/hooks/useCreateNewChat"; -import { ApiUser } from "@/lib/businessModules/chat/shared/types"; -import { extractHomeserverNameFromUserMatrixID } from "@/lib/businessModules/chat/shared/utils"; - -export interface DirectChatFormValues { - invite: string[]; -} - -export interface GroupChatFormValues { - name: string; - invite?: string[]; -} - -export interface InviteFormValues { - invite: string[] | null; -} - -export interface SettingsFormValues { - historyVisibility?: HistoryVisibility; -} - -export function ChatsPane() { - const [usersModalOpen, setUsersModalOpen] = useState(false); - const [groupChatModalOpen, setGroupModalOpen] = useState(false); - const [inviteModalOpen, setInviteModalOpen] = useState(false); - const [settingsModalOpen, setSettingsModalOpen] = useState(false); - const [clickedRoomId, setClickedRoomId] = useState<string>(); - const [userList, setUserList] = useState<ApiUser[] | undefined>(); - const [alert, setAlert] = useState<AlertProps>(); - const snackbar = useSnackbar(); - const { matrixClient } = useChatClientContext(); - - const { createNewChatRoom, createNewDirectMessage } = useCreateNewChat(); - const { getImageUrl, invite, handleChangeHistoryVisibility } = useChatUtils(); - const { roomList } = useChatRoomList(); - const loggedInUserId = matrixClient.getUserId(); - - async function getUsers() { - try { - const data = await matrixClient.searchUserDirectory({ - term: extractHomeserverNameFromUserMatrixID(loggedInUserId), - }); - if (data.results.length) { - const users = data.results.filter( - (user) => - !!user && user.user_id !== loggedInUserId && !!user.display_name, - ); - setUserList(users); - setAlert(undefined); - } - } catch (error) { - setAlert({ - title: "Es hat nicht funktioniert, die Benutzer abzurufen.", - color: "danger", - }); - logger.warn("Search user directory failed", error); - } - } - - async function handleAddDirectMessage() { - setUsersModalOpen(true); - await getUsers(); - } - - async function handleAddGroupChat() { - setGroupModalOpen(true); - await getUsers(); - } - - async function inviteToRoom(roomId: string) { - setInviteModalOpen(true); - setClickedRoomId(roomId); - await getUsers(); - } - - function handleRoomSettings(roomId: string) { - setSettingsModalOpen(true); - setClickedRoomId(roomId); - } - - const initialSettingFormValues = useMemo<SettingsFormValues>(() => { - const room = roomList.find((room) => room.room.roomId === clickedRoomId); - return { historyVisibility: room?.room.getHistoryVisibility() }; - }, [clickedRoomId, roomList]); - - async function handleStartDirectMessage(values: DirectChatFormValues) { - try { - await createNewDirectMessage({ - invite: values.invite, - }); - } catch { - snackbar.error("Chat konnte nicht erstellt werden"); - } - setUsersModalOpen(false); - } - - async function handleStartGroupChat(values: GroupChatFormValues) { - try { - await createNewChatRoom(values); - } catch { - snackbar.error("Chat konnte nicht erstellt werden"); - } - setGroupModalOpen(false); - } - - async function handleInvite(formValues: InviteFormValues) { - try { - if (!formValues.invite) return; - if (!clickedRoomId) return; - await Promise.all( - formValues.invite.map((userId) => invite(clickedRoomId, userId)), - ); - setClickedRoomId(undefined); - setInviteModalOpen(false); - snackbar.confirmation("Die Einladung wurde gesendet."); - } catch { - snackbar.error("Benutzer könnte nicht eingeladen werden"); - } - } - - async function submitSettings(formValues: SettingsFormValues) { - try { - if (!formValues.historyVisibility) return; - if (!clickedRoomId) return; - await handleChangeHistoryVisibility( - clickedRoomId, - formValues.historyVisibility, - ); - setClickedRoomId(undefined); - setSettingsModalOpen(false); - snackbar.confirmation("Die Einstellungen wurden gespeichert."); - } catch { - snackbar.error( - "Das Speichern der Einstellungen ist leider fehlgeschlagen.", - ); - } - } - - function validateDMForm( - values: DirectChatFormValues, - ): FormikErrors<DirectChatFormValues> { - const errors: FormikErrors<DirectChatFormValues> = {}; - if (values.invite?.length > 0) { - return errors; - } - errors.invite = "Bitte wählen Sie mindestens einen Benutzer aus."; - return errors; - } - - function validateGroupChatForm( - values: GroupChatFormValues, - ): FormikErrors<GroupChatFormValues> { - const errors: FormikErrors<GroupChatFormValues> = {}; - if (values.name) { - return errors; - } - errors.name = "Bitte fügen Sie den Chatnamen hinzu"; - return errors; - } - - function validateInviteForm( - values: InviteFormValues, - ): FormikErrors<InviteFormValues> { - const errors: FormikErrors<InviteFormValues> = {}; - if (values.invite?.length) { - return errors; - } - errors.invite = "Wählen Sie einen Benutzer aus."; - return errors; - } - - function validateSettingsForm( - values: SettingsFormValues, - ): FormikErrors<SettingsFormValues> { - const errors: FormikErrors<SettingsFormValues> = {}; - if (values.historyVisibility) { - return errors; - } - errors.historyVisibility = "Wählen Sie einen Benutzer aus."; - return errors; - } - - const usersToInvite = useMemo(() => { - const roomToInviteTo = roomList.find( - (roomWithCommunicationType) => - roomWithCommunicationType.room.roomId === clickedRoomId, - ); - const usersInRoom = roomToInviteTo?.room - .getMembers() - .filter((member) => member.membership === "join"); - const joinedUsers = usersInRoom?.map((joinedUser) => joinedUser.userId); - if (!joinedUsers?.length) { - return userList; - } - return userList?.filter( - (apiUser) => !joinedUsers.includes(apiUser.user_id), - ); - }, [clickedRoomId, roomList, userList]); - - return ( - <> - <Sheet - sx={{ - overflow: { sm: "hidden visible" }, - flex: 1, - padding: 0, - borderRadius: 0, - display: "flex", - flexDirection: "column", - }} - > - <ChatList - handleAddChat={handleAddDirectMessage} - buttonLabel="Private Nachricht" - roomList={roomList.filter( - (room) => - room.communicationType === CommunicationType.DirectMessage, - )} - /> - <ChatList - handleAddChat={handleAddGroupChat} - buttonLabel="Gruppenchat" - roomList={roomList.filter( - (room) => room.communicationType === CommunicationType.PublicRoom, - )} - handleInvite={inviteToRoom} - handleSettings={handleRoomSettings} - /> - </Sheet> - <DirectMessageModal - open={usersModalOpen} - onClose={() => setUsersModalOpen(false)} - userList={userList} - onSubmit={handleStartDirectMessage} - validateForm={validateDMForm} - alertProps={alert} - getImageUrl={getImageUrl} - /> - <GroupChatModal - open={groupChatModalOpen} - onClose={() => setGroupModalOpen(false)} - onSubmit={handleStartGroupChat} - validateForm={validateGroupChatForm} - getImageUrl={getImageUrl} - userList={userList} - alertProps={alert} - /> - <InviteToChatModal - open={inviteModalOpen} - onClose={() => setInviteModalOpen(false)} - userList={usersToInvite} - onSubmit={handleInvite} - validateForm={validateInviteForm} - getImageUrl={getImageUrl} - alertProps={alert} - /> - <ChatSettingsModal - open={settingsModalOpen} - onClose={() => setSettingsModalOpen(false)} - onSubmit={submitSettings} - validateForm={validateSettingsForm} - initialFormValues={initialSettingFormValues} - /> - </> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/DirectMessageModal.tsx b/employee-portal/src/lib/businessModules/chat/components/DirectMessageModal.tsx deleted file mode 100644 index 69de033f6d9026bbae15d77c8fda9d7b2871fe9b..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/DirectMessageModal.tsx +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Alert } from "@eshg/lib-portal/components/Alert"; -import { SubmitButton } from "@eshg/lib-portal/components/buttons/SubmitButton"; -import { FormPlus } from "@eshg/lib-portal/components/form/FormPlus"; -import { Box, Sheet } from "@mui/joy"; -import { Formik } from "formik"; -import { isEmpty } from "remeda"; - -import { DirectChatFormValues } from "@/lib/businessModules/chat/components/ChatsPane"; -import { UsersAutocomplete } from "@/lib/businessModules/chat/components/UsersAutocomplete"; -import { - ApiUser, - ChatBaseModal, -} from "@/lib/businessModules/chat/shared/types"; -import { BaseModal } from "@/lib/shared/components/BaseModal"; - -interface DirectMessageModalProps extends ChatBaseModal<DirectChatFormValues> { - userList: ApiUser[] | undefined; - getImageUrl: (url?: string) => string | null; -} - -export function DirectMessageModal({ - open, - onClose, - userList, - validateForm, - onSubmit, - getImageUrl, - alertProps, -}: Readonly<DirectMessageModalProps>) { - return ( - <BaseModal - open={open} - onClose={onClose} - modalTitle="Neue Direktnachricht erstellen" - > - <Sheet - variant="soft" - sx={{ - minHeight: "20rem", - backgroundColor: "transparent", - }} - > - {!userList?.length ? ( - alertProps && <Alert {...alertProps} /> - ) : ( - <Formik<DirectChatFormValues> - initialValues={{ invite: [] }} - onSubmit={onSubmit} - validate={validateForm} - > - {({ isSubmitting, errors }) => ( - <FormPlus> - <Sheet - variant="soft" - sx={{ - backgroundColor: "transparent", - display: "flex", - flexDirection: "column", - p: 0, - }} - > - <UsersAutocomplete - name="invite" - label="Benutzer einladen" - usersList={userList} - multiple={true} - getImageUrl={getImageUrl} - /> - <Box - sx={{ - minHeight: "6.5rem", - display: "flex", - flexDirection: "column", - justifyContent: "flex-end", - }} - > - <SubmitButton - submitting={isSubmitting} - disabled={!isEmpty(errors)} - sx={{ mt: 1 }} - > - Neue Nachricht - </SubmitButton> - </Box> - </Sheet> - </FormPlus> - )} - </Formik> - )} - </Sheet> - </BaseModal> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/GhostButton.tsx b/employee-portal/src/lib/businessModules/chat/components/GhostButton.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5359eb7b1be8a6e5be1f2eb6d0293c87bedc0d9b --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/GhostButton.tsx @@ -0,0 +1,11 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +// eslint-disable-next-line no-restricted-imports +import { Link, LinkProps } from "@mui/joy"; + +export function GhostButton(props: LinkProps) { + return <Link component="button" level="title-md" {...props} />; +} diff --git a/employee-portal/src/lib/businessModules/chat/components/GroupChatMember.tsx b/employee-portal/src/lib/businessModules/chat/components/GroupChatMember.tsx new file mode 100644 index 0000000000000000000000000000000000000000..44c695cc619a235526827a2b2c79180f4385fea6 --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/GroupChatMember.tsx @@ -0,0 +1,81 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import CloseOutlinedIcon from "@mui/icons-material/CloseOutlined"; +import { IconButton, Stack, Typography } from "@mui/joy"; +import { RoomMember } from "matrix-js-sdk"; + +import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; +import { logger } from "@/lib/businessModules/chat/shared/helpers"; +import { + getDepartmentNameFromUserId, + getMemberAvatarUrl, +} from "@/lib/businessModules/chat/shared/utils"; + +import { ChatAvatar } from "./ChatAvatar"; + +interface GroupChatMemberProps { + member: RoomMember; + isRoomCreator: boolean; + isAdmin: boolean; +} + +export function GroupChatMember({ + member, + isRoomCreator, + isAdmin, +}: GroupChatMemberProps) { + const usernameAndOrganisation = getDepartmentNameFromUserId(member.userId); + const { matrixClient } = useChatClientContext(); + + const avatarUrl = getMemberAvatarUrl(matrixClient, member); + + function handleRemove() { + logger.debug("Remove this user", member.userId); + } + + return ( + <Stack + direction="row" + sx={{ + alignItems: "center", + width: "100%", + }} + > + <ChatAvatar + name={member.name} + userId={member.userId} + avatarUrl={avatarUrl} + size="lg" + /> + <Stack sx={{ flex: 1, overflow: "hidden", marginLeft: 2 }}> + <Typography noWrap level="title-sm"> + {member.name} + </Typography> + {isRoomCreator && ( + <Typography noWrap level="body-sm"> + Admin + </Typography> + )} + <Typography noWrap level="body-sm"> + {usernameAndOrganisation?.username} + </Typography> + <Typography + noWrap + level="body-sm" + textColor="text.secondary" + sx={{ textTransform: "capitalize" }} + > + {usernameAndOrganisation?.organisationName} + </Typography> + </Stack> + {isAdmin && ( + <IconButton color="primary" onClick={handleRemove}> + <CloseOutlinedIcon /> + </IconButton> + )} + </Stack> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/GroupChatModal.tsx b/employee-portal/src/lib/businessModules/chat/components/GroupChatModal.tsx deleted file mode 100644 index 15108103bea6038220fddb2f30710e452049f5b1..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/GroupChatModal.tsx +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Alert } from "@eshg/lib-portal/components/Alert"; -import { SubmitButton } from "@eshg/lib-portal/components/buttons/SubmitButton"; -import { FormPlus } from "@eshg/lib-portal/components/form/FormPlus"; -import { InputField } from "@eshg/lib-portal/components/formFields/InputField"; -import { Box, Sheet } from "@mui/joy"; -import { Formik } from "formik"; -import { isEmpty } from "remeda"; - -import { GroupChatFormValues } from "@/lib/businessModules/chat/components/ChatsPane"; -import { UsersAutocomplete } from "@/lib/businessModules/chat/components/UsersAutocomplete"; -import { - ApiUser, - ChatBaseModal, -} from "@/lib/businessModules/chat/shared/types"; -import { BaseModal } from "@/lib/shared/components/BaseModal"; - -interface GroupChatModalProps extends ChatBaseModal<GroupChatFormValues> { - userList: ApiUser[] | undefined; - getImageUrl: (url?: string) => string | null; -} - -export function GroupChatModal({ - open, - onClose, - onSubmit, - userList, - validateForm, - alertProps, - getImageUrl, -}: Readonly<GroupChatModalProps>) { - return ( - <BaseModal - open={open} - onClose={onClose} - modalTitle="Neuen Gruppenchat erstellen" - > - <Sheet - variant="soft" - sx={{ - minHeight: "20rem", - backgroundColor: "transparent", - }} - > - {!userList?.length ? ( - alertProps && <Alert {...alertProps} /> - ) : ( - <Formik<GroupChatFormValues> - initialValues={{ invite: [], name: "" }} - onSubmit={onSubmit} - validate={validateForm} - > - {({ isSubmitting, errors }) => ( - <FormPlus> - <Sheet - variant="soft" - sx={{ - backgroundColor: "transparent", - display: "flex", - flexDirection: "column", - p: 0, - }} - > - <Box - sx={{ - minHeight: "6.5rem", - display: "flex", - flexDirection: "column", - justifyContent: "flex-end", - }} - > - <InputField type="text" name="name" label="Chat name" /> - <UsersAutocomplete - name="invite" - label="Benutzer einladen" - usersList={userList} - multiple={true} - getImageUrl={getImageUrl} - /> - <SubmitButton - submitting={isSubmitting} - disabled={!isEmpty(errors)} - sx={{ mt: 1 }} - > - Füge einen neuen Gruppenchat hinzu - </SubmitButton> - </Box> - </Sheet> - </FormPlus> - )} - </Formik> - )} - </Sheet> - </BaseModal> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/InviteToChatModal.tsx b/employee-portal/src/lib/businessModules/chat/components/InviteToChatModal.tsx deleted file mode 100644 index ed0735d571823963235e604a172ca0945a075c7c..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/InviteToChatModal.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Alert } from "@eshg/lib-portal/components/Alert"; -import { SubmitButton } from "@eshg/lib-portal/components/buttons/SubmitButton"; -import { FormPlus } from "@eshg/lib-portal/components/form/FormPlus"; -import { Box, Sheet } from "@mui/joy"; -import { Formik } from "formik"; -import { isEmpty } from "remeda"; - -import { InviteFormValues } from "@/lib/businessModules/chat/components/ChatsPane"; -import { UsersAutocomplete } from "@/lib/businessModules/chat/components/UsersAutocomplete"; -import { - ApiUser, - ChatBaseModal, -} from "@/lib/businessModules/chat/shared/types"; -import { BaseModal } from "@/lib/shared/components/BaseModal"; - -interface InviteToChatModalProps extends ChatBaseModal<InviteFormValues> { - userList: ApiUser[] | undefined; - getImageUrl: (url?: string) => string | null; -} - -export function InviteToChatModal({ - open, - onClose, - onSubmit, - userList, - validateForm, - alertProps, - getImageUrl, -}: Readonly<InviteToChatModalProps>) { - return ( - <BaseModal open={open} onClose={onClose} modalTitle="Zum Chat einladen"> - <Sheet - variant="soft" - sx={{ - minHeight: "20rem", - backgroundColor: "transparent", - }} - > - {!userList?.length ? ( - alertProps && <Alert {...alertProps} /> - ) : ( - <Formik<InviteFormValues> - initialValues={{ invite: [] }} - onSubmit={onSubmit} - validate={validateForm} - > - {({ isSubmitting, errors }) => ( - <FormPlus> - <Box - sx={{ - display: "flex", - minHeight: "18rem", - flexDirection: "column", - justifyContent: "space-between", - }} - > - <UsersAutocomplete - name="invite" - label="Benutzer einladen" - usersList={userList} - multiple={true} - getImageUrl={getImageUrl} - /> - <SubmitButton - submitting={isSubmitting} - disabled={!isEmpty(errors)} - > - Invite - </SubmitButton> - </Box> - </FormPlus> - )} - </Formik> - )} - </Sheet> - </BaseModal> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/LeaveChatConfirmation.tsx b/employee-portal/src/lib/businessModules/chat/components/LeaveChatConfirmation.tsx new file mode 100644 index 0000000000000000000000000000000000000000..524937d78d49d4e478615a4d598270301226ce6b --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/LeaveChatConfirmation.tsx @@ -0,0 +1,22 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + ConfirmationDialog, + ConfirmationDialogProps, +} from "@/lib/shared/components/confirmationDialog/ConfirmationDialog"; + +export function LeaveChatConfirmation(props: ConfirmationDialogProps) { + return ( + <ConfirmationDialog + color="danger" + title="Wollen Sie den Chat wirklich verlassen?" + description="Wenn Sie den Chat verlassen, können Sie keine neuen Nachrichten mehr empfangen." + key="leave-room-dialog" + confirmLabel="Verlassen" + {...props} + /> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/MessageInput.tsx b/employee-portal/src/lib/businessModules/chat/components/MessageInput.tsx deleted file mode 100644 index 1c9939d96e95808211d9f2863b47164363febf66..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/MessageInput.tsx +++ /dev/null @@ -1,209 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -/* eslint-disable react/forbid-elements */ -import { ClickAwayListener } from "@mui/base"; -import SendRoundedIcon from "@mui/icons-material/SendRounded"; -import { - Box, - Button, - Menu, - MenuItem, - Stack, - Textarea, - Typography, -} from "@mui/joy"; -import { RoomMember } from "matrix-js-sdk/lib/matrix"; -import { ChangeEvent, FormEvent, KeyboardEvent, useRef, useState } from "react"; -import { useDebouncedCallback } from "use-debounce"; - -interface MessageInput { - handleUserTyping: (roomId: string, isTyping: boolean) => Promise<void>; - selectedRoomId: string; - onSubmit: (text: string, mentionedUser?: string[]) => Promise<void> | null; - roomMembers: RoomMember[]; -} -export function MessageInput({ - onSubmit, - roomMembers, - handleUserTyping, - selectedRoomId, -}: Readonly<MessageInput>) { - const [textareaValue, setTextareaValue] = useState(""); - const [filteredUsers, setFilteredUsers] = useState<RoomMember[]>([]); - const [mentionedUsers, setMentionedUsers] = useState<string[]>([]); - const [selectedUserIndex, setSelectedUserIndex] = useState<number>(); - const textareaRef = useRef<HTMLDivElement>(null); - - async function handleSubmit(e: FormEvent) { - e.preventDefault(); - await onSubmit(textareaValue, mentionedUsers); - setTextareaValue(""); - setMentionedUsers([]); - } - - const debouncedHandleUserTyping = useDebouncedCallback( - (isTyping: boolean) => handleUserTyping(selectedRoomId, isTyping), - 500, - { leading: true }, - ); - - function handleTextareaChange(event: ChangeEvent<HTMLTextAreaElement>) { - const { value } = event.target; - setTextareaValue(value); - - // Check if we are currently mentioning someone - const mentionIndex = value.lastIndexOf("@"); - if ( - mentionIndex !== -1 && - (mentionIndex === 0 || - value[mentionIndex - 1] === " " || - value[mentionIndex - 1] === "\n") - ) { - const currentMention = value.slice(mentionIndex + 1); - const filtered = roomMembers.filter((user) => - user.name.toLowerCase().includes(currentMention.toLowerCase()), - ); - setFilteredUsers(filtered); - setSelectedUserIndex(0); - } else { - setFilteredUsers([]); - setSelectedUserIndex(undefined); - } - - if (value === "") { - void debouncedHandleUserTyping(false); - } else { - void debouncedHandleUserTyping(true); - } - } - function handleUserModalClose() { - setFilteredUsers([]); - setSelectedUserIndex(undefined); - } - - async function handleKeydown(event: KeyboardEvent<HTMLTextAreaElement>) { - if ( - event.key === "@" && - (textareaValue.length === 0 || - textareaValue.endsWith(" ") || - textareaValue.endsWith("\n")) - ) { - setFilteredUsers(roomMembers); - setSelectedUserIndex(0); - return; - } - if (event.key === "Enter" && !event.shiftKey && filteredUsers.length > 0) { - event.preventDefault(); - handleUserSelect(filteredUsers[selectedUserIndex ?? 0]); - return; - } - - if (event.key === "Enter" && !event.shiftKey) { - event.preventDefault(); - await onSubmit(textareaValue, mentionedUsers); - setTextareaValue(""); - setMentionedUsers([]); - } - - if (event.key === "ArrowDown" && filteredUsers.length > 0) { - event.preventDefault(); - setSelectedUserIndex( - (prevIndex) => ((prevIndex ?? 0) + 1) % filteredUsers.length, - ); - } - - if (event.key === "ArrowUp" && filteredUsers.length > 0) { - event.preventDefault(); - setSelectedUserIndex( - (prevIndex) => - ((prevIndex ?? 0) - 1 + filteredUsers.length) % filteredUsers.length, - ); - } - } - - function handleUserSelect(user: RoomMember | undefined) { - if (!user) return; - const mentionIndex = textareaValue.lastIndexOf("@"); - const newText = textareaValue.slice(0, mentionIndex + 1) + user.name + " "; - setTextareaValue(newText); - setFilteredUsers([]); - setSelectedUserIndex(undefined); - setMentionedUsers((prev) => [...prev, user.userId]); - // Focus back to the textarea - const textareaNode = textareaRef.current?.childNodes?.[0] as - | HTMLTextAreaElement - | undefined; - if (textareaNode) { - textareaNode.focus(); - } - } - - return ( - <Box sx={{ px: 2, pb: 3 }}> - <form onSubmit={handleSubmit}> - <ClickAwayListener onClickAway={handleUserModalClose}> - <Menu - disablePortal - keepMounted - open={filteredUsers.length > 0} - anchorEl={textareaRef.current} - sx={{ width: "calc(100% - 2rem)" }} - > - {filteredUsers.map((user, index) => ( - <MenuItem - key={user.userId} - selected={index === selectedUserIndex} - onClick={() => handleUserSelect(user)} - sx={{ - display: "flex", - justifyContent: "space-between", - alignItems: "center", - }} - > - <Typography level="body-sm">{user.name}</Typography>{" "} - <Typography level="body-xs">{user.userId}</Typography> - </MenuItem> - ))} - </Menu> - </ClickAwayListener> - <Textarea - ref={textareaRef} - placeholder="Geben Sie hier etwas ein ..." - aria-label="Message" - onChange={handleTextareaChange} - onKeyDown={handleKeydown} - minRows={2} - maxRows={10} - value={textareaValue} - endDecorator={ - <Stack - direction="row" - justifyContent="flex-end" - alignItems="center" - flexGrow={1} - sx={{ - pt: 1, - pb: 0.5, - borderTop: "1px solid", - borderColor: "divider", - }} - > - <Button - size="sm" - color="primary" - sx={{ alignSelf: "center", borderRadius: "sm" }} - endDecorator={<SendRoundedIcon />} - type="submit" - > - Send - </Button> - </Stack> - } - /> - </form> - </Box> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/MessagesList.tsx b/employee-portal/src/lib/businessModules/chat/components/MessagesList.tsx deleted file mode 100644 index 071cbf0f9afaf6a24332be279781e4c20b1c847d..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/MessagesList.tsx +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { Alert } from "@eshg/lib-portal/components/Alert"; -import { Avatar, ListItem } from "@mui/joy"; - -import { BadgeAvatar } from "@/lib/businessModules/chat/components/BadgeAvatar"; -import { ChatBubble } from "@/lib/businessModules/chat/components/ChatBubble"; -import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; -import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; -import { useChatUtils } from "@/lib/businessModules/chat/shared/hooks/useChatUtils"; -import { useReadConfirmation } from "@/lib/businessModules/chat/shared/hooks/useReadConfirmation"; -import { Message } from "@/lib/businessModules/chat/shared/types"; -import { formatUserReceipts } from "@/lib/businessModules/chat/shared/utils"; - -interface MessagesListProps { - selectedRoomId: string; - messages: Message[]; -} -export function MessagesList({ - selectedRoomId, - messages, -}: Readonly<MessagesListProps>) { - const { - userSettings: { sharePresence, showReadConfirmation }, - } = useChat(); - const { matrixClient, usersPresence } = useChatClientContext(); - const loggedInUserId = matrixClient.getUserId(); - const { readConfirmationsPerRoom } = - useReadConfirmation(showReadConfirmation); - const confirmationsArr = formatUserReceipts( - readConfirmationsPerRoom[selectedRoomId], - ); - const { getImageUrl, getUser } = useChatUtils(); - - if (!loggedInUserId) { - return ( - <Alert - title="Selected Room not found" - message="Unknown error occured" - color="danger" - /> - ); - } - - return ( - <> - {messages.map((message: Message) => { - const isYou = message.sender?.userId === loggedInUserId; - const presenceStatus = message.sender?.userId - ? usersPresence[message.sender.userId] - : undefined; - const confirmationIds = confirmationsArr?.[message.id]; - - const receiptUsers = - showReadConfirmation && Array.isArray(confirmationIds) - ? confirmationIds.map((userId) => getUser(userId)) - : []; - - return ( - <ListItem - key={message.id} - sx={{ flexDirection: isYou ? "row-reverse" : "row", px: 0, py: 1 }} - > - <BadgeAvatar status={sharePresence ? presenceStatus : undefined}> - <Avatar - src={getImageUrl(message.sender?.avatarUrl) ?? undefined} - variant="outlined" - sx={{ ...(isYou ? { ml: 2 } : { mr: 2 }) }} - /> - </BadgeAvatar> - <ChatBubble - variant={isYou ? "sent" : "received"} - loggedInUserId={loggedInUserId} - message={message} - receiptUsers={receiptUsers.filter( - (user) => user?.userId !== loggedInUserId, - )} - getImageUrl={getImageUrl} - /> - </ListItem> - ); - })} - </> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/MessagesPane.tsx b/employee-portal/src/lib/businessModules/chat/components/MessagesPane.tsx deleted file mode 100644 index 00cfdada49366ce471c07e7d77a5ebb9aa5adb01..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/MessagesPane.tsx +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { List, Stack, Typography } from "@mui/joy"; -import { useEffect, useRef } from "react"; - -import { MessageInput } from "@/lib/businessModules/chat/components/MessageInput"; -import { MessagesList } from "@/lib/businessModules/chat/components/MessagesList"; -import { MessagesPaneHeader } from "@/lib/businessModules/chat/components/MessagesPaneHeader"; -import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; -import { useChatRoomList } from "@/lib/businessModules/chat/shared/hooks/useChatRoomList"; -import { useChatUtils } from "@/lib/businessModules/chat/shared/hooks/useChatUtils"; -import { useRoomMessages } from "@/lib/businessModules/chat/shared/hooks/useRoomMessages"; -import { useSelectedRoomId } from "@/lib/businessModules/chat/shared/hooks/useSelectedRoomId"; -import { useTyping } from "@/lib/businessModules/chat/shared/hooks/useTyping"; -import { getDirectMessageMember } from "@/lib/businessModules/chat/shared/utils"; - -export function MessagesPane() { - const { - userSettings: { showTypingNotification }, - } = useChat(); - const { typingUsersList, handleUserTyping } = useTyping( - showTypingNotification, - ); - const { roomList } = useChatRoomList(); - const { getRoomAvatar, getImageUrl, getUser } = useChatUtils(); - const { selectedRoomId } = useSelectedRoomId(); - const { - messages, - handleSendMessage, - paginateMessages, - isLoading, - canPaginate, - } = useRoomMessages(); - const selectedRoom = roomList.find( - (roomItem) => roomItem.room.roomId === selectedRoomId, - ); - const typingUsers = typingUsersList[selectedRoomId]; - const messagesWrapperRef = useRef<HTMLUListElement>(null); - const offset = 5; - - useEffect(() => { - const container = messagesWrapperRef.current; - if (container === null) { - return; - } - async function handleScroll() { - if (!container) { - return; - } - if ( - Math.abs(container.scrollTop) + container.offsetHeight >= - container.scrollHeight - offset && - !isLoading - ) { - const previousScrollHeight = container.scrollHeight; - const previousScrollTop = container.scrollTop; - - await paginateMessages(); - - const newScrollHeight = container.scrollHeight; - container.scrollTop = - previousScrollTop + (newScrollHeight - previousScrollHeight - offset); - } - } - function onScroll() { - void handleScroll(); - } - container.addEventListener("scroll", onScroll); - - // Cleanup event listener on component unmount - return () => { - container.removeEventListener("scroll", onScroll); - }; - }, [canPaginate, isLoading, paginateMessages]); - - if (!selectedRoomId || !selectedRoom) { - return null; - } - - return ( - <Stack - sx={{ - height: "100%", - backgroundColor: "background.level1", - }} - > - <MessagesPaneHeader - name={selectedRoom.room.name} - avatarUrl={getRoomAvatar(selectedRoom)} - userId={getDirectMessageMember(selectedRoom)?.userId} - communicationType={selectedRoom.communicationType} - roomMembers={selectedRoom.room.getJoinedMembers()} - key={`${selectedRoom.room.roomId}-header`} - getImageUrl={getImageUrl} - /> - <List - sx={{ - display: "flex", - flex: 1, - px: 2, - py: 3, - overflowY: "scroll", - flexDirection: "column-reverse", - }} - ref={messagesWrapperRef} - > - <MessagesList selectedRoomId={selectedRoomId} messages={messages} /> - </List> - <Typography - level="body-sm" - sx={{ - mx: 2, - mb: 1, - visibility: typingUsersList[selectedRoom.room.roomId]?.length - ? "visible" - : "hidden", - }} - > - {typingUsers?.map( - (userId, index) => - `${getUser(userId)?.displayName}${typingUsers.length - 1 !== index ? ", " : ""} `, - )} - {(typingUsers?.length ?? 0) > 1 ? "schreiben..." : "schreibt..."} - </Typography> - <MessageInput - key={`${selectedRoom.room.roomId}-input`} - onSubmit={handleSendMessage} - handleUserTyping={handleUserTyping} - selectedRoomId={selectedRoom.room.roomId} - roomMembers={selectedRoom.room.getMembers()} - /> - </Stack> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/MessagesPaneHeader.tsx b/employee-portal/src/lib/businessModules/chat/components/MessagesPaneHeader.tsx deleted file mode 100644 index 44339c2661068bfb1bb98fd6be6bb3c5e7079984..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/MessagesPaneHeader.tsx +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { - Avatar, - Dropdown, - Menu, - MenuButton, - Stack, - Typography, -} from "@mui/joy"; -import { RoomMember } from "matrix-js-sdk/lib/matrix"; -import { useState } from "react"; - -import { BadgeAvatar } from "@/lib/businessModules/chat/components/BadgeAvatar"; -import { ChatListItemAvatar } from "@/lib/businessModules/chat/components/ChatListItemAvatar"; -import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; -import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; -import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; - -interface MessagesPaneHeaderProps { - name: string; - avatarUrl?: string; - userId?: string; - communicationType: CommunicationType; - roomMembers?: RoomMember[]; - getImageUrl: (url?: string) => string | null; -} - -export function MessagesPaneHeader({ - name, - avatarUrl, - userId, - communicationType, - roomMembers, - getImageUrl, -}: Readonly<MessagesPaneHeaderProps>) { - const [snackbarOpen, setSnackbarOpen] = useState(false); - const { - userSettings: { sharePresence }, - } = useChat(); - const clientContext = useChatClientContext(); - const usersPresence = clientContext.usersPresence; - const presenceStatus = userId ? usersPresence[userId] : undefined; - - return ( - <Dropdown> - <MenuButton - onClick={() => setSnackbarOpen((prevState) => !prevState)} - sx={{ - margin: 0, - padding: 0, - }} - > - <Stack - direction="row" - spacing={2} - alignItems="center" - sx={{ - borderColor: "divider", - backgroundColor: "background.body", - minHeight: "4rem", - width: "100%", - margin: 0, - }} - p={1} - > - <BadgeAvatar status={sharePresence ? presenceStatus : undefined}> - <ChatListItemAvatar - avatarUrl={avatarUrl} - communicationType={communicationType} - /> - </BadgeAvatar> - <Stack> - <Typography fontWeight="lg" fontSize="md" noWrap> - {name} - </Typography> - </Stack> - </Stack> - </MenuButton> - - <Menu open={snackbarOpen} placement="bottom-start"> - <Stack - direction="column" - spacing={2} - sx={{ - backgroundColor: "background.body", - minHeight: "4rem", - padding: 2, - }} - p={1} - > - {communicationType === CommunicationType.PublicRoom && ( - <Stack - direction="column" - spacing={1} - sx={{ justifyContent: "flex-start" }} - > - <Typography>Teilnehmer im Chat</Typography> - {roomMembers?.map((member) => ( - <Stack - key={member.userId} - direction="row" - sx={{ alignItems: "center" }} - spacing={1} - > - <BadgeAvatar - status={ - sharePresence ? usersPresence[member.userId] : undefined - } - > - <Avatar - src={ - getImageUrl(member.user?.avatarUrl ?? undefined) ?? - undefined - } - variant="outlined" - size={"sm"} - /> - </BadgeAvatar> - <Typography - fontWeight="sm" - fontSize="sm" - noWrap - key={member.userId} - > - {member.name} - </Typography> - </Stack> - ))} - </Stack> - )} - {communicationType === CommunicationType.DirectMessage && ( - <Stack direction="column" spacing={1}> - <Typography>User ID: </Typography> - <Typography fontWeight="sm" fontSize="sm" noWrap> - {userId} - </Typography> - </Stack> - )} - </Stack> - </Menu> - </Dropdown> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/OnlineStatus.tsx b/employee-portal/src/lib/businessModules/chat/components/OnlineStatus.tsx index f47afd643106b94a9aded4c99b78b12e10269fd4..53d143d53a489231f205c5c9efd9b8d437d77949 100644 --- a/employee-portal/src/lib/businessModules/chat/components/OnlineStatus.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/OnlineStatus.tsx @@ -5,15 +5,18 @@ import { Box, Stack, Typography } from "@mui/joy"; -import { Presence } from "@/lib/businessModules/chat/shared/types"; +import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; import { getStatusColor } from "@/lib/businessModules/chat/shared/utils"; interface OnlineStatusProps { + userId: string; name?: string; - presence?: Presence; } -export function OnlineStatus({ name, presence }: OnlineStatusProps) { +export function OnlineStatus({ userId, name }: OnlineStatusProps) { + const { usersPresence } = useChatClientContext(); + const presence = usersPresence[userId]; + return ( <Stack direction="row" diff --git a/employee-portal/src/lib/businessModules/chat/components/UsersAutocomplete.tsx b/employee-portal/src/lib/businessModules/chat/components/UsersAutocomplete.tsx index dec6977e7e6c2ad24b2f5feef2f59e2fcf4bb3ed..ddf13db0b5554560a06fedb2b9e24e0fde76d78b 100644 --- a/employee-portal/src/lib/businessModules/chat/components/UsersAutocomplete.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/UsersAutocomplete.tsx @@ -3,15 +3,14 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import SearchIcon from "@mui/icons-material/Search"; import { Autocomplete, AutocompleteOption, - Avatar, Box, Chip, ChipDelete, FormHelperText, - FormLabel, Typography, } from "@mui/joy"; import { useField } from "formik"; @@ -19,31 +18,29 @@ import { HTMLAttributes } from "react"; import { ApiUser } from "@/lib/businessModules/chat/shared/types"; +import { ChatAvatar } from "./ChatAvatar"; + interface UsersAutocompleteProps { name: string; - label: string; - usersList: ApiUser[]; + placeholder: string; + usersList: (ApiUser & { department?: string })[]; multiple: boolean; - getImageUrl: (url?: string) => string | null; } export function UsersAutocomplete({ name, - label, + placeholder, usersList, multiple, - getImageUrl, }: Readonly<UsersAutocompleteProps>) { const [field, meta, helpers] = useField<string | string[] | null>(name); return ( <Box> - <FormLabel htmlFor={name} sx={{ mt: 2 }}> - {label} - </FormLabel> <Autocomplete name="invite" multiple={multiple} value={field.value} + size="lg" onChange={async (_, newValue) => { if (multiple) { const emptyValue: string[] = []; @@ -52,11 +49,30 @@ export function UsersAutocomplete({ await helpers.setValue(newValue); } }} + placeholder={placeholder} options={usersList.map((opt) => opt.user_id)} getOptionLabel={(value) => usersList?.find((apiUser) => apiUser.user_id === value) ?.display_name ?? value } + startDecorator={<SearchIcon />} + slotProps={{ + input: { + sx: { + "&::placeholder": { + color: "primary.300", + }, + }, + }, + }} + sx={{ + ".MuiAutocomplete-popupIndicator": { + display: "none", + }, + backgroundColor: "background.surface", + borderColor: "primary.300", + height: "3.25rem", + }} renderOption={(props, option) => { const apiUser = usersList?.find((user) => user.user_id === option); if (!apiUser) return null; @@ -70,9 +86,10 @@ export function UsersAutocomplete({ key={option} {...componentProps} sx={{ - display: "flex", + display: "grid", alignItems: "center", - justifyContent: "space-between", + gridTemplateColumns: "repeat(2, auto 1fr)", + gap: 2, }} > <Box @@ -82,15 +99,22 @@ export function UsersAutocomplete({ gap: 1, }} > - <Avatar - color="primary" - variant="soft" + <ChatAvatar + name={apiUser.display_name} + userId={apiUser.user_id} + avatarUrl={apiUser.avatar_url ?? null} size="sm" - src={getImageUrl(apiUser?.avatar_url) ?? undefined} /> - <Typography level="body-sm">{apiUser.display_name}</Typography> + <Typography level="title-md">{apiUser.display_name}</Typography> </Box> - <Typography level="body-xs">{apiUser.user_id}</Typography> + {apiUser.department && ( + <Typography + level="body-md" + sx={{ color: "neutral.400", textTransform: "capitalize" }} + > + {apiUser.department} + </Typography> + )} </AutocompleteOption> ); }} @@ -102,9 +126,10 @@ export function UsersAutocomplete({ ); return ( <Chip - variant="outlined" + variant="soft" key={key} endDecorator={<ChipDelete {...tagProps} />} + color="primary" > {apiUser?.display_name} </Chip> diff --git a/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatBubble.tsx b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatBubble.tsx new file mode 100644 index 0000000000000000000000000000000000000000..7542ade9f5205127c6abda22fd1fda9635b97f41 --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatBubble.tsx @@ -0,0 +1,140 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import Box from "@mui/joy/Box"; +import Sheet from "@mui/joy/Sheet"; +import Stack from "@mui/joy/Stack"; +import Typography from "@mui/joy/Typography"; +import { format, isToday } from "date-fns"; +import { User } from "matrix-js-sdk/lib/matrix"; +import { ReactNode } from "react"; + +import { ChatAvatar } from "@/lib/businessModules/chat/components/ChatAvatar"; +import { ReadingReceipt } from "@/lib/businessModules/chat/components/chatPanel/ReadingReceipt"; +import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; +import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; +import { Message } from "@/lib/businessModules/chat/shared/types"; +import { formatDateForChat } from "@/lib/businessModules/chat/shared/utils"; + +interface ChatBubbleProps { + message: Message; + variant: "sent" | "received"; + loggedInUserId: string; + receiptUsers: (User | null)[]; +} + +export function ChatBubble({ + variant, + message, + loggedInUserId, + receiptUsers, +}: Readonly<ChatBubbleProps>) { + const { matrixClient } = useChatClientContext(); + const { userSettings } = useChat(); + const isSent = variant === "sent"; + const mentionedNames = message.mentions + ?.map((mention) => { + const user = matrixClient.getUser(mention); + return user?.displayName; + }) + .filter((item) => !!item) as string[]; + + return ( + <Stack direction="column" alignItems="flex-start"> + <Stack + direction="row" + justifyContent={ + message.sender?.userId === loggedInUserId ? "end" : "start" + } + spacing={1} + sx={{ mb: 0.25 }} + width="100%" + > + <Typography textColor="text.secondary" sx={{ fontSize: "0.875rem" }}> + {message.sender?.userId === loggedInUserId + ? "" + : message.sender?.displayName} + </Typography> + {message.timestamp && ( + <Typography textColor="text.secondary" sx={{ fontSize: "0.875rem" }}> + {isToday(message.timestamp) + ? `${format(message.timestamp, "HH:MM")} Uhr` + : formatDateForChat(message.timestamp)} + </Typography> + )} + </Stack> + <Box sx={{ width: "100%", display: "flex", alignItems: "flex-end" }}> + {!isSent && ( + <ChatAvatar + name={message.sender?.displayName} + userId={message.sender?.userId} + avatarUrl={message.sender?.avatarUrl ?? null} + /> + )} + <Sheet + color={isSent ? "primary" : "neutral"} + variant={isSent ? "solid" : "soft"} + sx={{ + p: 1, + borderRadius: "md", + backgroundColor: isSent ? "primary.500" : "neutral.100", + wordBreak: "break-word", + marginLeft: 1, + marginRight: 1, + }} + > + <Typography + level="body-md" + sx={{ + color: isSent ? "background.body" : "text.primary", + overflowWrap: "break-word", + }} + > + {mentionedNames + ? splitMessageWithNames(message.content, mentionedNames) + : message.content} + </Typography> + </Sheet> + {isSent && ( + <ReadingReceipt + isReadReceiptEnabled={userSettings.showReadConfirmation} + isRead={receiptUsers?.length > 0} + /> + )} + </Box> + </Stack> + ); +} + +function splitMessageWithNames( + messageContent: string, + mentionedNames?: string[], +) { + const contentParts: ReactNode[] = []; + let remainingContent = messageContent; + + mentionedNames?.forEach((name) => { + const nameIndex = remainingContent.indexOf(name); + + if (nameIndex !== -1) { + const beforeName = remainingContent.substring(0, nameIndex); + if (beforeName) { + contentParts.push(<>{beforeName}</>); + } + contentParts.push( + <Typography level="title-md" textColor="inherit"> + {name} + </Typography>, + ); + remainingContent = remainingContent.substring(nameIndex + name.length); + } + }); + + if (remainingContent) { + contentParts.push(<>{remainingContent}</>); + } + + return contentParts; +} diff --git a/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatHeader.tsx b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatHeader.tsx deleted file mode 100644 index bdc3327b596889f6d159026e178ecf19551c58db..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatHeader.tsx +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import NotificationsOffOutlinedIcon from "@mui/icons-material/NotificationsOffOutlined"; -import { Stack, Typography, useTheme } from "@mui/joy"; - -import { ChatAvatar } from "@/lib/businessModules/chat/components/ChatAvatar"; -import { OnlineStatus } from "@/lib/businessModules/chat/components/OnlineStatus"; -import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; -import { RoomUserPresence } from "@/lib/businessModules/chat/shared/types"; - -export interface ChatHeaderProps { - id: string; - roomName: string; - communicationType?: CommunicationType; - avatarUrl?: string; - usersPresence?: RoomUserPresence[]; -} - -export function ChatHeader({ - roomName, - communicationType = CommunicationType.DirectMessage, - avatarUrl, - usersPresence, -}: ChatHeaderProps) { - const theme = useTheme(); - - // TO DO - finish mute feature - const muteIndicator = false; - - return ( - <Stack - direction="row" - spacing={2} - sx={{ alignItems: "center", width: "100%" }} - > - <ChatAvatar - name={roomName} - communicationType={communicationType} - avatarUrl={avatarUrl} - size="lg" - /> - <Stack sx={{ flex: 1, overflow: "hidden" }}> - <Stack direction="row" spacing={0.5} sx={{ alignItems: "center" }}> - <Typography noWrap level="h3"> - {roomName} - </Typography> - {muteIndicator && ( - <NotificationsOffOutlinedIcon - sx={{ - width: "1.125rem", - height: "1.125rem", - color: theme.palette.neutral.outlinedDisabledColor, - }} - /> - )} - </Stack> - <Stack direction="row" spacing={2}> - {usersPresence?.map((item) => ( - <OnlineStatus - key={item.userId} - presence={item.presence} - name={usersPresence.length > 1 ? item.name : undefined} - /> - ))} - </Stack> - </Stack> - </Stack> - ); -} diff --git a/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatMessages.tsx b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatMessages.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5c6a19431571d3e9fc63b7faa82ea7916b15987e --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatMessages.tsx @@ -0,0 +1,153 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Box, Divider, List, ListItem, Typography, useTheme } from "@mui/joy"; +import { isSameDay, startOfDay } from "date-fns"; +import { Fragment, useEffect, useRef } from "react"; + +import { ChatIllustrationBackground } from "@/lib/businessModules/chat/components/ChatIllustrationBackground"; +import { ChatBubble } from "@/lib/businessModules/chat/components/chatPanel/ChatBubble"; +import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; +import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; +import { useReadConfirmation } from "@/lib/businessModules/chat/shared/hooks/useReadConfirmation"; +import { useRoomMessages } from "@/lib/businessModules/chat/shared/hooks/useRoomMessages"; +import { useTyping } from "@/lib/businessModules/chat/shared/hooks/useTyping"; +import { + Message, + RoomWithCommunicationType, +} from "@/lib/businessModules/chat/shared/types"; +import { + formatUserReceipts, + getDayLabel, +} from "@/lib/businessModules/chat/shared/utils"; + +interface ChatMessagesProps { + room: RoomWithCommunicationType; +} + +export function ChatMessages({ room }: Readonly<ChatMessagesProps>) { + const { + userSettings: { showReadConfirmation }, + } = useChat(); + const { matrixClient } = useChatClientContext(); + const loggedInUserId = matrixClient.getUserId(); + const { readConfirmationsPerRoom } = + useReadConfirmation(showReadConfirmation); + const confirmationsArr = formatUserReceipts( + readConfirmationsPerRoom[room.room.roomId], + ); + const { + userSettings: { showTypingNotification }, + } = useChat(); + const { typingUsersList } = useTyping(showTypingNotification); + const typingUsers = typingUsersList[room.room.roomId]; + const { messages } = useRoomMessages(); + const theme = useTheme(); + const messagesWrapperRef = useRef<HTMLUListElement>(null); + const wrapperRef = useRef<HTMLDivElement>(null); + + useEffect(() => { + wrapperRef.current?.scrollTo( + 0, + messagesWrapperRef.current?.scrollHeight ?? 0, + ); + }, [room]); + + if (!loggedInUserId) { + return <ChatIllustrationBackground />; + } + + return ( + <Box + sx={{ + overflowY: "auto", + flex: 1, + }} + ref={wrapperRef} + > + <List + ref={messagesWrapperRef} + sx={{ + display: "flex", + flexDirection: "column-reverse", + }} + > + {messages?.map((message: Message, index: number) => { + const isYou = message.sender?.userId === loggedInUserId; + + const confirmationIds = confirmationsArr?.[message.id]; + + const receiptUsers = + showReadConfirmation && Array.isArray(confirmationIds) + ? confirmationIds.map((userId) => matrixClient.getUser(userId)) + : []; + const nextMessage = messages[index + 1]; + const shouldShowDivider = + index !== messages.length - 1 && + message.timestamp && + nextMessage?.timestamp && + nextMessage && + !isSameDay( + startOfDay(message.timestamp), + startOfDay(nextMessage.timestamp), + ); + + return ( + <Fragment key={message.id}> + <ListItem + sx={{ + flexDirection: isYou ? "row-reverse" : "row", + paddingX: theme.spacing(3), + paddingY: 0, + marginBottom: 3, + }} + > + <ChatBubble + variant={isYou ? "sent" : "received"} + loggedInUserId={loggedInUserId} + message={message} + receiptUsers={receiptUsers.filter( + (user) => user?.userId !== loggedInUserId, + )} + /> + </ListItem> + {shouldShowDivider && message.timestamp && ( + <Divider + sx={{ + padding: 2, + paddingTop: 0, + "&::before, &::after": { + backgroundColor: "neutral.200", + }, + }} + > + <Typography level="title-sm" textColor="neutral.500"> + {getDayLabel(message.timestamp)} + </Typography> + </Divider> + )} + </Fragment> + ); + })} + </List> + {!!typingUsers?.length && ( + <Typography + level="body-sm" + sx={{ + mx: 2, + mb: 1, + visibility: typingUsers?.length ? "visible" : "hidden", + }} + > + {typingUsers?.map( + (userId, index) => + `${matrixClient.getUser(userId)?.displayName}${typingUsers.length - 1 !== index ? ", " : ""} `, + )} + {(typingUsers?.length ?? 0) > 1 ? "tippen..." : "tippt..."} + </Typography> + )} + </Box> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatPanel.tsx b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatPanel.tsx index f4aad546ad80c0334b436d0109ebfcfd2c9b05a4..acecc0bc70aa9cac54950602de0ab5910a7837e0 100644 --- a/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatPanel.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatPanel.tsx @@ -3,18 +3,157 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { ChatPanelHeader } from "./ChatPanelHeader"; +import { Alert, AlertProps } from "@eshg/lib-portal/components/Alert"; +import { Box } from "@mui/joy"; +import { useEffect, useState } from "react"; +import { isNonNullish } from "remeda"; + +import { chatColumnHeaderHeight } from "@/lib/businessModules/chat/components/ChatColumnHeaderWrapper"; +import { ChatIllustrationBackground } from "@/lib/businessModules/chat/components/ChatIllustrationBackground"; +import { ChatMessages } from "@/lib/businessModules/chat/components/chatPanel/ChatMessages"; +import { ChatPanelHeader } from "@/lib/businessModules/chat/components/chatPanel/ChatPanelHeader"; +import { MessageInput } from "@/lib/businessModules/chat/components/chatPanel/MessageInput"; +import { NewDirectChat } from "@/lib/businessModules/chat/components/chatPanel/NewDirectChat"; +import { NewGroupChat } from "@/lib/businessModules/chat/components/chatPanel/NewGroupChat"; +import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; +import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; +import { ChatPanelView } from "@/lib/businessModules/chat/shared/enums"; +import { logger } from "@/lib/businessModules/chat/shared/helpers"; +import { useRoomMessages } from "@/lib/businessModules/chat/shared/hooks/useRoomMessages"; +import { useTyping } from "@/lib/businessModules/chat/shared/hooks/useTyping"; +import { ApiUser } from "@/lib/businessModules/chat/shared/types"; +import { + extractHomeserverNameFromUserMatrixID, + getDepartmentNameFromUserId, + getRoomNameAndCommunicationType, +} from "@/lib/businessModules/chat/shared/utils"; +import { sidebarPadding } from "@/lib/shared/components/sidebar/Sidebar"; export interface ChatPanelProps { - roomId: string; + roomId: string | null; isOpenChatSettings: boolean; toggleChatSettingsView(): void; + chatPanelView: ChatPanelView; + setChatPanelView: (viewType: ChatPanelView) => void; } -export function ChatPanel(props: ChatPanelProps) { - return ( - <> - <ChatPanelHeader {...props} /> - </> - ); +export function ChatPanel({ + roomId, + toggleChatSettingsView, + chatPanelView, + setChatPanelView, +}: Readonly<ChatPanelProps>) { + const { + userSettings: { showTypingNotification }, + } = useChat(); + const { handleUserTyping } = useTyping(showTypingNotification); + const { handleSendMessage } = useRoomMessages(); + const [userList, setUserList] = useState< + (ApiUser & { department?: string })[] | undefined + >(); + const { matrixClient } = useChatClientContext(); + const loggedInUserId = matrixClient.getUserId(); + const [alert, setAlert] = useState<AlertProps>(); + const selectedRoom = matrixClient.getRoom(roomId ?? undefined); + const roomWithCommunicationType = selectedRoom + ? getRoomNameAndCommunicationType(selectedRoom) + : undefined; + + useEffect(() => { + async function getUsers() { + try { + const data = await matrixClient.searchUserDirectory({ + term: extractHomeserverNameFromUserMatrixID(loggedInUserId), + }); + if (data.results.length) { + const users = data.results.filter( + (user) => + !!user && user.user_id !== loggedInUserId && !!user.display_name, + ); + const usersWithDepartment = await Promise.all( + users.map(async (user) => { + const userInfo = await matrixClient.whoami(); + const department = getDepartmentNameFromUserId( + userInfo.user_id, + )?.organisationName; + return { + ...user, + department, + }; + }), + ); + setUserList(usersWithDepartment); + setAlert(undefined); + } + } catch (error) { + setAlert({ + title: "Es hat nicht funktioniert, die Benutzer abzurufen.", + color: "danger", + }); + logger.warn("Search user directory failed", error); + } + } + if ( + chatPanelView === ChatPanelView.NewDirectChat || + chatPanelView === ChatPanelView.NewGroupChat + ) { + void getUsers(); + } + }, [chatPanelView, loggedInUserId, matrixClient]); + + if (isNonNullish(alert)) { + return ( + <Box sx={{ paddingRight: sidebarPadding, paddingLeft: sidebarPadding }}> + <Alert {...alert} color="danger" /> + </Box> + ); + } + if (chatPanelView === ChatPanelView.NoChatSelected) { + return <ChatIllustrationBackground />; + } + if (chatPanelView === ChatPanelView.NewDirectChat) { + return ( + <NewDirectChat + cancel={() => setChatPanelView(ChatPanelView.NoChatSelected)} + userList={userList} + setChatPanelView={setChatPanelView} + /> + ); + } + if (chatPanelView === ChatPanelView.NewGroupChat) { + return ( + <NewGroupChat + cancel={() => setChatPanelView(ChatPanelView.NoChatSelected)} + userList={userList} + setChatPanelView={setChatPanelView} + /> + ); + } + if (roomId && roomWithCommunicationType) { + return ( + <> + <ChatPanelHeader + roomId={roomId} + toggleChatSettingsView={toggleChatSettingsView} + /> + <Box + sx={{ + height: `calc(100% - ${chatColumnHeaderHeight})`, + display: "flex", + flexDirection: "column", + }} + > + <ChatMessages room={roomWithCommunicationType} /> + <MessageInput + handleUserTyping={handleUserTyping} + selectedRoomId={roomId} + sendMessage={handleSendMessage} + roomMembers={roomWithCommunicationType.room.getMembers()} + /> + </Box> + </> + ); + } else { + return <ChatIllustrationBackground />; + } } diff --git a/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatPanelHeader.tsx b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatPanelHeader.tsx index d671f261d5d236ee61016e4aed26b4a36d933e5e..ebf93f7c500e4d1dd0637d0135cac2b7b83d19d4 100644 --- a/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatPanelHeader.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ChatPanelHeader.tsx @@ -3,109 +3,121 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import GroupOutlinedIcon from "@mui/icons-material/GroupOutlined"; +import LogoutOutlinedIcon from "@mui/icons-material/LogoutOutlined"; import MoreVertIcon from "@mui/icons-material/MoreVert"; -import NotificationsNoneOutlinedIcon from "@mui/icons-material/NotificationsNoneOutlined"; -import PushPinOutlinedIcon from "@mui/icons-material/PushPinOutlined"; -import { IconButton, Stack, styled } from "@mui/joy"; +import PersonOutlinedIcon from "@mui/icons-material/PersonOutlined"; +import { + Dropdown, + IconButton, + ListItemDecorator, + Menu, + MenuButton, + MenuItem, + Stack, +} from "@mui/joy"; +import { useState } from "react"; import { ChatColumnHeaderWrapper } from "@/lib/businessModules/chat/components/ChatColumnHeaderWrapper"; -import { ChatHeader } from "@/lib/businessModules/chat/components/chatPanel/ChatHeader"; -import { ChatPanelProps } from "@/lib/businessModules/chat/components/chatPanel/ChatPanel"; -import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; -import { logger } from "@/lib/businessModules/chat/shared/helpers"; -import { useChatUtils } from "@/lib/businessModules/chat/shared/hooks/useChatUtils"; -import { RoomUserPresence } from "@/lib/businessModules/chat/shared/types"; -import { getRoomNameAndCommunicationType } from "@/lib/businessModules/chat/shared/utils"; +import { ChatHeader } from "@/lib/businessModules/chat/components/ChatHeader"; +import { LeaveChatConfirmation } from "@/lib/businessModules/chat/components/LeaveChatConfirmation"; +import { useChatSearchParams } from "@/lib/businessModules/chat/shared/hooks/useChatSearchParams"; +import { useRoomInfo } from "@/lib/businessModules/chat/shared/hooks/useRoomInfo"; +import { isDMRoom, leaveRoom } from "@/lib/businessModules/chat/shared/utils"; -const StyledIconButton = styled(IconButton)(({ theme }) => ({ - borderColor: theme.palette.primary.outlinedBorder, -})); +export interface ChatPanelHeaderProps { + roomId: string; + toggleChatSettingsView: () => void; +} export function ChatPanelHeader({ roomId, toggleChatSettingsView, -}: ChatPanelProps) { - const { matrixClient, usersPresence } = useChatClientContext(); - const { getRoomAvatar } = useChatUtils(); - - const room = matrixClient.getRoom(roomId); +}: Readonly<ChatPanelHeaderProps>) { + const roomInfo = useRoomInfo(roomId); + const { clearChatParams } = useChatSearchParams(); + const [isOpen, setIsOpen] = useState(false); - if (!room) { + if (!roomInfo) { return <ChatColumnHeaderWrapper />; } - const roomWithType = getRoomNameAndCommunicationType(room); - const avatarUrl = getRoomAvatar(roomWithType); - - const roomUsersPresence: RoomUserPresence[] = room - .getMembers() - .filter((member) => member.userId !== matrixClient.getUserId()) - .map((m) => ({ - userId: m.userId, - name: m.name, - presence: usersPresence[m.userId], - })); - - function handleNotificationClick() { - logger.debug("toggle notification"); + function handleRoomSettingsClick() { + toggleChatSettingsView(); } - function handleRoomPinClick() { - logger.debug("toggle pin"); + function handleLeaveRoomClick() { + setIsOpen(false); + clearChatParams(); + void leaveRoom(roomInfo.matrixClient, roomId); } - function handleRoomSettingsClick() { - toggleChatSettingsView(); - } + const roomSettingsItem = isDMRoom(roomInfo.communicationType) ? ( + <> + <ListItemDecorator> + <PersonOutlinedIcon /> + </ListItemDecorator> + Kontakt anzeigen + </> + ) : ( + <> + <ListItemDecorator> + <GroupOutlinedIcon /> + </ListItemDecorator> + Mitglieder anzeigen + </> + ); return ( - <ChatColumnHeaderWrapper> - <Stack - direction="row" - spacing={2} - sx={{ - justifyContent: "space-between", - alignItems: "center", - height: "100%", - }} - > - <ChatHeader - id={roomWithType.room.roomId} - roomName={roomWithType.room.name} - communicationType={roomWithType.communicationType} - avatarUrl={avatarUrl} - usersPresence={roomUsersPresence} - /> + <> + <ChatColumnHeaderWrapper> <Stack direction="row" - spacing={1} + spacing={2} sx={{ + justifyContent: "space-between", alignItems: "center", + height: "100%", }} > - <StyledIconButton - variant="outlined" - aria-label="toggle notification" - onClick={handleNotificationClick} - > - <NotificationsNoneOutlinedIcon color="primary" /> - </StyledIconButton> - <StyledIconButton - variant="outlined" - aria-label="toggle room pin" - onClick={handleRoomPinClick} - > - <PushPinOutlinedIcon color="primary" /> - </StyledIconButton> - <StyledIconButton - variant="outlined" - aria-label="toggle notification" - onClick={handleRoomSettingsClick} + <ChatHeader {...roomInfo} /> + <Stack + direction="row" + spacing={1} + sx={{ + alignItems: "center", + }} > - <MoreVertIcon color="primary" /> - </StyledIconButton> + <Dropdown> + <MenuButton + slots={{ root: IconButton }} + slotProps={{ root: { variant: "outlined", color: "primary" } }} + aria-label="open room options" + > + <MoreVertIcon color="primary" /> + </MenuButton> + <Menu placement="bottom-end"> + <MenuItem onClick={handleRoomSettingsClick}> + {roomSettingsItem} + </MenuItem> + <MenuItem onClick={() => setIsOpen(true)}> + <ListItemDecorator> + <LogoutOutlinedIcon /> + </ListItemDecorator> + {isDMRoom(roomInfo.communicationType) + ? "Verlassen" + : "Gruppe verlassen"} + </MenuItem> + </Menu> + </Dropdown> + </Stack> </Stack> - </Stack> - </ChatColumnHeaderWrapper> + </ChatColumnHeaderWrapper> + <LeaveChatConfirmation + open={isOpen} + onClose={() => setIsOpen(false)} + onConfirm={handleLeaveRoomClick} + /> + </> ); } diff --git a/employee-portal/src/lib/businessModules/chat/components/chatPanel/InputComponent.tsx b/employee-portal/src/lib/businessModules/chat/components/chatPanel/InputComponent.tsx new file mode 100644 index 0000000000000000000000000000000000000000..b7adc7c7295998652585fd0060c6ce35615b3b74 --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/chatPanel/InputComponent.tsx @@ -0,0 +1,225 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { ClickAwayListener } from "@mui/base"; +import SendOutlinedIcon from "@mui/icons-material/SendOutlined"; +import { + Box, + IconButton, + Input, + Menu, + MenuItem, + Stack, + Typography, +} from "@mui/joy"; +import { useField, useFormikContext } from "formik"; +import { RoomMember } from "matrix-js-sdk/lib/matrix"; +import { ChangeEvent, KeyboardEvent, useRef, useState } from "react"; +import { useDebouncedCallback } from "use-debounce"; + +import { ChatAvatar } from "@/lib/businessModules/chat/components/ChatAvatar"; +import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; +import { logger } from "@/lib/businessModules/chat/shared/helpers"; +import { getMemberAvatarUrl } from "@/lib/businessModules/chat/shared/utils"; + +interface MessageFormValues { + message: string; + mentionedUsers?: string[]; +} +interface InputComponent { + name: string; + selectFieldName: string; + handleUserTyping?: (roomId: string, isTyping: boolean) => Promise<void>; + selectedRoomId?: string; + roomMembers: RoomMember[]; +} + +export function InputComponent({ + name, + selectFieldName, + roomMembers, + handleUserTyping, + selectedRoomId, +}: Readonly<InputComponent>) { + const { matrixClient } = useChatClientContext(); + const [filteredUsers, setFilteredUsers] = useState<RoomMember[]>([]); + const [selectedUserIndex, setSelectedUserIndex] = useState<number>(); + const inputRef = useRef<HTMLDivElement>(null); + + const [field, _meta, helpers] = useField<string>(name); + const [selectField, _metaField, selectHelpers] = useField< + string[] | undefined + >(selectFieldName); + const { submitForm, resetForm } = useFormikContext<MessageFormValues>(); + + const debouncedHandleUserTyping = useDebouncedCallback( + (isTyping: boolean) => handleUserTyping?.(selectedRoomId ?? "", isTyping), + 500, + { leading: true }, + ); + + async function handleInputChange(event: ChangeEvent<HTMLInputElement>) { + const { value } = event.target || {}; + await helpers.setValue(value); + + // Check if we are currently mentioning someone + const mentionIndex = value.lastIndexOf("@"); + if ( + mentionIndex !== -1 && + (mentionIndex === 0 || + value[mentionIndex - 1] === " " || + value[mentionIndex - 1] === "\n") + ) { + const currentMention = value.slice(mentionIndex + 1); + const filtered = roomMembers.filter((user) => + user.name.toLowerCase().includes(currentMention.toLowerCase()), + ); + setFilteredUsers(filtered); + setSelectedUserIndex(0); + } else { + setFilteredUsers([]); + setSelectedUserIndex(undefined); + } + + void debouncedHandleUserTyping(false); + } + function handleUserModalClose() { + setFilteredUsers([]); + setSelectedUserIndex(undefined); + } + + async function handleKeydown(event: KeyboardEvent<HTMLInputElement>) { + const inputValue = field.value; + if (!inputValue) return; + if ( + event.key === "@" && + (inputValue.length === 0 || + inputValue.endsWith(" ") || + inputValue.endsWith("\n")) + ) { + setFilteredUsers(roomMembers); + setSelectedUserIndex(0); + return; + } + if (event.key === "Enter" && !event.shiftKey && filteredUsers.length > 0) { + event.preventDefault(); + await handleUserSelect(filteredUsers[selectedUserIndex ?? 0]); + return; + } + + if (event.key === "Enter" && !event.shiftKey) { + try { + event.preventDefault(); + await submitForm(); + resetForm(); + } catch (error) { + logger.warn("Sending message failed", error); + } + } + + if (event.key === "ArrowDown" && filteredUsers.length > 0) { + event.preventDefault(); + setSelectedUserIndex( + (prevIndex) => ((prevIndex ?? 0) + 1) % filteredUsers.length, + ); + } + + if (event.key === "ArrowUp" && filteredUsers.length > 0) { + event.preventDefault(); + setSelectedUserIndex( + (prevIndex) => + ((prevIndex ?? 0) - 1 + filteredUsers.length) % filteredUsers.length, + ); + } + } + + async function handleUserSelect(user: RoomMember | undefined) { + const inputValue = field.value; + if (!user) return; + const mentionIndex = inputValue?.lastIndexOf("@"); + const newText = + inputValue?.slice(0, (mentionIndex ?? 0) + 1) + user.name + " "; + await helpers.setValue(newText); + setFilteredUsers([]); + setSelectedUserIndex(undefined); + await selectHelpers.setValue([...(selectField.value ?? []), user.userId]); + // Focus back to the input + const inputNode = inputRef.current?.childNodes?.[0] as + | HTMLTextAreaElement + | undefined; + if (inputNode) { + inputNode.focus(); + } + } + + return ( + <Box sx={{ p: 2 }}> + <ClickAwayListener onClickAway={handleUserModalClose}> + <Menu + disablePortal + keepMounted + open={filteredUsers.length > 0} + anchorEl={inputRef.current} + > + <Typography level="title-sm" sx={{ padding: "0.5rem 1rem" }}> + Person erwähnen + </Typography> + {filteredUsers.map((user, index) => ( + <MenuItem + key={user.userId} + selected={index === selectedUserIndex} + onClick={() => handleUserSelect(user)} + sx={{ + display: "flex", + justifyContent: "space-between", + alignItems: "center", + }} + > + <Stack + direction="row" + sx={{ alignItems: "center", gap: 1, marginRight: 3 }} + > + <ChatAvatar + userId={user.userId} + name={user.name} + avatarUrl={getMemberAvatarUrl(matrixClient, user)} + size="sm" + /> + <Typography level="title-md">{user.name}</Typography> + </Stack> + <Typography level="body-md" textColor="neutral.400"> + {user.userId} + </Typography> + </MenuItem> + ))} + </Menu> + </ClickAwayListener> + <Input + ref={inputRef} + placeholder="Nachricht schreiben" + onChange={handleInputChange} + onKeyDown={handleKeydown} + value={field.value} + variant="plain" + name={name} + sx={{ + height: "4.25rem", + backgroundColor: "background.level1", + "--Input-paddingInline": "1rem", + "--Input-radius": "0.5rem", + ".MuiIconButton-root": { + marginRight: "0", + }, + }} + color="neutral" + endDecorator={ + <IconButton size="sm" color="primary" type="submit"> + <SendOutlinedIcon /> + </IconButton> + } + /> + </Box> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/chatPanel/MessageInput.tsx b/employee-portal/src/lib/businessModules/chat/components/chatPanel/MessageInput.tsx new file mode 100644 index 0000000000000000000000000000000000000000..8bc47bc49abc677e8a14bca63fda158e340848ce --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/chatPanel/MessageInput.tsx @@ -0,0 +1,67 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { FormPlus } from "@eshg/lib-portal/components/form/FormPlus"; +import { Box } from "@mui/joy"; +import { Formik, FormikErrors } from "formik"; +import { RoomMember } from "matrix-js-sdk/lib/matrix"; + +import { InputComponent } from "@/lib/businessModules/chat/components/chatPanel/InputComponent"; +import { logger } from "@/lib/businessModules/chat/shared/helpers"; + +export interface MessageFormValues { + message: string; + mentionedUsers?: string[]; +} +function validateMessageForm( + values: MessageFormValues, +): FormikErrors<MessageFormValues> { + const errors: FormikErrors<MessageFormValues> = {}; + if (values.message?.length > 0) { + return errors; + } + errors.message = "Gib etwas ein, um das Gespräch zu beginnen!"; + return errors; +} +interface MessageInput { + handleUserTyping?: (roomId: string, isTyping: boolean) => Promise<void>; + selectedRoomId?: string; + sendMessage: (text: string, mentionedUser?: string[]) => Promise<void> | null; + roomMembers: RoomMember[]; +} + +export function MessageInput({ + sendMessage, + roomMembers, + handleUserTyping, + selectedRoomId, +}: Readonly<MessageInput>) { + return ( + <Box> + <Formik<MessageFormValues> + onSubmit={async (values, helpers) => { + try { + await sendMessage(values.message, values.mentionedUsers); + helpers.resetForm(); + } catch (error) { + logger.warn("Sending message failed", error); + } + }} + initialValues={{ message: "", mentionedUsers: undefined }} + validate={validateMessageForm} + > + <FormPlus> + <InputComponent + name="message" + selectFieldName="mentionedUsers" + handleUserTyping={handleUserTyping} + selectedRoomId={selectedRoomId} + roomMembers={roomMembers} + /> + </FormPlus> + </Formik> + </Box> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/chatPanel/NewDirectChat.tsx b/employee-portal/src/lib/businessModules/chat/components/chatPanel/NewDirectChat.tsx new file mode 100644 index 0000000000000000000000000000000000000000..f6c299bfde59e4bd7abf6774d1ff7cea965d6bb7 --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/chatPanel/NewDirectChat.tsx @@ -0,0 +1,145 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { FormPlus } from "@eshg/lib-portal/components/form/FormPlus"; +import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; +import { Box, Button, Stack, Typography, useTheme } from "@mui/joy"; +import { Formik, FormikErrors } from "formik"; +import { isObjectType } from "remeda"; + +import { ChatIllustrationBackground } from "@/lib/businessModules/chat/components/ChatIllustrationBackground"; +import { UsersAutocomplete } from "@/lib/businessModules/chat/components/UsersAutocomplete"; +import { ChatMessages } from "@/lib/businessModules/chat/components/chatPanel/ChatMessages"; +import { InputComponent } from "@/lib/businessModules/chat/components/chatPanel/InputComponent"; +import { ChatPanelView } from "@/lib/businessModules/chat/shared/enums"; +import { useChatSearchParams } from "@/lib/businessModules/chat/shared/hooks/useChatSearchParams"; +import { useCreateNewChat } from "@/lib/businessModules/chat/shared/hooks/useCreateNewChat"; +import { useSendMessage } from "@/lib/businessModules/chat/shared/hooks/useSendMessage"; +import { ApiUser } from "@/lib/businessModules/chat/shared/types"; + +export interface DirectChatFormValues { + invite: string; + message: string; +} + +interface NewDirectChatProps { + cancel: () => void; + userList: (ApiUser & { department?: string })[] | undefined; + setChatPanelView: (viewType: ChatPanelView) => void; +} +export function NewDirectChat({ + cancel, + userList, + setChatPanelView, +}: Readonly<NewDirectChatProps>) { + const { createNewDirectMessage, findExisingRoom } = useCreateNewChat(); + const { sendMessage } = useSendMessage(); + const theme = useTheme(); + const { setRoomIdParam } = useChatSearchParams(); + + const snackbar = useSnackbar(); + + async function handleStartDirectMessage(values: DirectChatFormValues) { + try { + const newRoomId = await createNewDirectMessage({ + invite: [values.invite], + }); + if (!newRoomId) { + return; + } + await sendMessage(values.message, newRoomId); + setRoomIdParam(newRoomId); + setChatPanelView(ChatPanelView.ChatMessages); + } catch { + snackbar.error("Chat konnte nicht erstellt werden"); + } + } + function validateDMForm( + values: DirectChatFormValues, + ): FormikErrors<DirectChatFormValues> { + const errors: FormikErrors<DirectChatFormValues> = {}; + if (!values.invite || values.invite === "") { + errors.invite = "Bitte wählen Sie mindestens einen Benutzer aus."; + } + if (!values.message || values.message === "") { + errors.message = "Gib etwas ein, um das Gespräch zu beginnen!"; + } + + return errors; + } + + return ( + <Box sx={{ height: "100%" }}> + <Formik<DirectChatFormValues> + initialValues={{ invite: "", message: "" }} + onSubmit={handleStartDirectMessage} + validate={validateDMForm} + > + {({ values }) => { + const existingChat = + values.invite && + !Array.isArray(values.invite) && + findExisingRoom(values.invite); + if (existingChat) { + setRoomIdParam(existingChat.room.roomId); + } + return ( + <FormPlus + style={{ + height: "100%", + display: "flex", + flexDirection: "column", + justifyContent: "space-between", + }} + > + <Box + sx={{ + padding: 2, + borderBottom: "1px solid", + borderColor: theme.palette.neutral.outlinedBorder, + }} + > + <Stack + direction="row" + justifyContent="space-between" + alignItems="center" + marginBottom={1} + height="2.25rem" + > + <Typography level="h3">Neue Direktnachricht</Typography> + <Button + variant="soft" + color="neutral" + type="button" + onClick={() => cancel()} + > + Abbrechen + </Button> + </Stack> + <UsersAutocomplete + name="invite" + placeholder="Empfänger:in auswählen" + usersList={userList ?? []} + multiple={false} + /> + </Box> + + {isObjectType(existingChat) && existingChat?.room.roomId ? ( + <ChatMessages room={existingChat} /> + ) : ( + <ChatIllustrationBackground /> + )} + <InputComponent + name="message" + selectFieldName="mentionedUsers" + roomMembers={[]} + /> + </FormPlus> + ); + }} + </Formik> + </Box> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/chatPanel/NewGroupChat.tsx b/employee-portal/src/lib/businessModules/chat/components/chatPanel/NewGroupChat.tsx new file mode 100644 index 0000000000000000000000000000000000000000..ad0c411febfb784c95150f86d59f40d45b5fd865 --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/chatPanel/NewGroupChat.tsx @@ -0,0 +1,146 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { FormPlus } from "@eshg/lib-portal/components/form/FormPlus"; +import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; +import { Box, Button, Stack, Typography, useTheme } from "@mui/joy"; +import { Formik, FormikErrors } from "formik"; + +import { ChatIllustrationBackground } from "@/lib/businessModules/chat/components/ChatIllustrationBackground"; +import { ChatInputField } from "@/lib/businessModules/chat/components/ChatInputField"; +import { UsersAutocomplete } from "@/lib/businessModules/chat/components/UsersAutocomplete"; +import { InputComponent } from "@/lib/businessModules/chat/components/chatPanel/InputComponent"; +import { ChatPanelView } from "@/lib/businessModules/chat/shared/enums"; +import { useChatSearchParams } from "@/lib/businessModules/chat/shared/hooks/useChatSearchParams"; +import { useCreateNewChat } from "@/lib/businessModules/chat/shared/hooks/useCreateNewChat"; +import { useSendMessage } from "@/lib/businessModules/chat/shared/hooks/useSendMessage"; +import { ApiUser } from "@/lib/businessModules/chat/shared/types"; + +export interface DirectChatFormValues { + invite: string[]; + chatName: string; + message: string; +} + +interface NewGroupChatProps { + cancel: () => void; + userList: (ApiUser & { department?: string })[] | undefined; + setChatPanelView: (viewType: ChatPanelView) => void; +} +export function NewGroupChat({ + cancel, + userList, + setChatPanelView, +}: Readonly<NewGroupChatProps>) { + const { createNewChatRoom } = useCreateNewChat(); + const { sendMessage } = useSendMessage(); + const theme = useTheme(); + const { setRoomIdParam } = useChatSearchParams(); + const snackbar = useSnackbar(); + + async function handleStartGroupChat(values: DirectChatFormValues) { + try { + const newRoomId = await createNewChatRoom({ + invite: values.invite, + name: values.chatName, + }); + if (!newRoomId) { + return; + } + await sendMessage(values.message, newRoomId); + setRoomIdParam(newRoomId); + setChatPanelView(ChatPanelView.ChatMessages); + } catch { + snackbar.error("Chat konnte nicht erstellt werden"); + } + } + function validateGroupForm( + values: DirectChatFormValues, + ): FormikErrors<DirectChatFormValues> { + const errors: FormikErrors<DirectChatFormValues> = {}; + if (values.invite?.length === 0) { + errors.invite = "Bitte wählen Sie mindestens einen Benutzer aus."; + } + if (!values.chatName || values.chatName === "") { + errors.chatName = "Bitte fügen Sie den Chatnamen hinzu"; + } + if (!values.message || values.message === "") { + errors.message = "Gib etwas ein, um das Gespräch zu beginnen!"; + } + + return errors; + } + + return ( + <Box sx={{ height: "100%" }}> + <Formik<DirectChatFormValues> + initialValues={{ invite: [], chatName: "", message: "" }} + onSubmit={handleStartGroupChat} + validate={validateGroupForm} + > + <FormPlus + style={{ + height: "100%", + display: "flex", + flexDirection: "column", + justifyContent: "space-between", + }} + > + <Box + sx={{ + padding: 2, + borderBottom: "1px solid", + borderColor: theme.palette.neutral.outlinedBorder, + }} + > + <Stack + direction="row" + justifyContent="space-between" + alignItems="center" + marginBottom={1} + height="2.25rem" + > + <Typography level="h3">Gruppenchat erstellen</Typography> + <Button + variant="soft" + color="neutral" + type="button" + onClick={() => cancel()} + > + Abbrechen + </Button> + </Stack> + <UsersAutocomplete + name="invite" + placeholder="Empfänger:in auswählen" + usersList={userList ?? []} + multiple={true} + /> + <ChatInputField + type="text" + name="chatName" + placeholder="Gruppenchat benennen" + label="" + aria-label="Chat name" + sx={{ + "--FormLabel-margin": 0, + marginTop: 1, + ".MuiInput-root": { + height: "3.25rem", + }, + }} + /> + </Box> + <ChatIllustrationBackground /> + <InputComponent + name="message" + selectFieldName="mentionedUsers" + roomMembers={[]} + /> + </FormPlus> + </Formik> + </Box> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/chatPanel/ReadingReceipt.tsx b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ReadingReceipt.tsx new file mode 100644 index 0000000000000000000000000000000000000000..985cb3383e91e947746a2ec351247a8003c140fc --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/chatPanel/ReadingReceipt.tsx @@ -0,0 +1,30 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import DoneIcon from "@mui/icons-material/Done"; +import DoneAllIcon from "@mui/icons-material/DoneAll"; + +interface ReadingReceiptProps { + isReadReceiptEnabled: boolean; + isRead?: boolean; +} + +export function ReadingReceipt({ + isReadReceiptEnabled, + isRead, +}: Readonly<ReadingReceiptProps>) { + if (!isReadReceiptEnabled) { + return ( + <DoneIcon + color="neutral" + sx={{ color: "danger.outlinedDisabledColor" }} + /> + ); + } + if (isRead) { + return <DoneAllIcon color="primary" />; + } + return <DoneIcon color="primary" />; +} diff --git a/employee-portal/src/lib/businessModules/chat/components/roomList/RoomList.tsx b/employee-portal/src/lib/businessModules/chat/components/roomList/RoomList.tsx index b7b0e2f986049b4cb1059111c5f7e738c2d2f222..252a87c1a79f3a14bf4566517d83451a4eb652cf 100644 --- a/employee-portal/src/lib/businessModules/chat/components/roomList/RoomList.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/roomList/RoomList.tsx @@ -3,44 +3,47 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { List } from "@mui/joy"; +import { List, ListItem, ListItemButton } from "@mui/joy"; import { RoomListItem } from "@/lib/businessModules/chat/components/roomList/RoomListItem"; -import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; -import { useChatUtils } from "@/lib/businessModules/chat/shared/hooks/useChatUtils"; -import { useSelectedRoomId } from "@/lib/businessModules/chat/shared/hooks/useSelectedRoomId"; +import { ChatPanelView } from "@/lib/businessModules/chat/shared/enums"; +import { useChatSearchParams } from "@/lib/businessModules/chat/shared/hooks/useChatSearchParams"; import { RoomWithCommunicationType } from "@/lib/businessModules/chat/shared/types"; -import { getDirectMessageMember } from "@/lib/businessModules/chat/shared/utils"; interface RoomListProps { roomList: RoomWithCommunicationType[]; + setChatPanelView: (viewType: ChatPanelView) => void; } -export function RoomList({ roomList }: RoomListProps) { - const { usersPresence } = useChatClientContext(); - const { getRoomAvatar } = useChatUtils(); - const { setSelectedRoomId, selectedRoomId } = useSelectedRoomId(); +export function RoomList({ + roomList, + setChatPanelView, +}: Readonly<RoomListProps>) { + const { selectedRoomId, setRoomIdParam } = useChatSearchParams(); return ( <List sx={{ py: 0 }}> {roomList.map((data) => { - const userId = getDirectMessageMember(data)?.userId; - const userPresence = userId ? usersPresence[userId] : undefined; - const avatarUrl = getRoomAvatar(data); - return ( - <RoomListItem - key={data.room.roomId} - id={data.room.roomId} - roomName={data.room.name} - presence={userPresence} - communicationType={data.communicationType} - avatarUrl={avatarUrl} - selectedRoomId={selectedRoomId} - handleSelectRoom={() => { - setSelectedRoomId(data.room.roomId); - }} - /> + <ListItem key={data.room.roomId}> + <ListItemButton + onClick={() => { + setRoomIdParam(data.room.roomId); + setChatPanelView(ChatPanelView.ChatMessages); + }} + selected={selectedRoomId === data.room.roomId} + color="neutral" + sx={{ + paddingX: 3, + paddingY: 2, + }} + > + <RoomListItem + room={data.room} + communicationType={data.communicationType} + /> + </ListItemButton> + </ListItem> ); })} </List> diff --git a/employee-portal/src/lib/businessModules/chat/components/roomList/RoomListItem.tsx b/employee-portal/src/lib/businessModules/chat/components/roomList/RoomListItem.tsx index f30c38f4164be59a38fe807f02414b0a1dfbb5cc..9b263a958e4f67819b7009815bec0e50c7232040 100644 --- a/employee-portal/src/lib/businessModules/chat/components/roomList/RoomListItem.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/roomList/RoomListItem.tsx @@ -4,81 +4,59 @@ */ import NotificationsOffOutlinedIcon from "@mui/icons-material/NotificationsOffOutlined"; -import { - Box, - ListItem, - ListItemButton, - Stack, - Typography, - useTheme, -} from "@mui/joy"; -import { useCallback, useEffect, useState } from "react"; +import { Box, Stack, Typography, useTheme } from "@mui/joy"; +import { Room } from "matrix-js-sdk"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { ChatAvatar } from "@/lib/businessModules/chat/components/ChatAvatar"; import { ReceiptStatus } from "@/lib/businessModules/chat/components/roomList/ReceiptStatus"; import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; -import { - Presence, - RoomLastMessage, -} from "@/lib/businessModules/chat/shared/types"; +import { RoomLastMessage } from "@/lib/businessModules/chat/shared/types"; import { convertMessageTimestamp, + getMemberAvatarUrl, + getRoomAvatarUrl, getRoomLastMessage, + isDMRoom, } from "@/lib/businessModules/chat/shared/utils"; export interface RoomListItemProps { - id: string; - roomName: string; - selectedRoomId: string | undefined; - handleSelectRoom: () => void; + room: Room; communicationType?: CommunicationType; - avatarUrl?: string; - presence?: Presence; } -export function RoomListItem(props: RoomListItemProps) { - const theme = useTheme(); - const selected = props.selectedRoomId === props.id; - - return ( - <ListItem> - <ListItemButton - onClick={props.handleSelectRoom} - selected={selected} - color="neutral" - sx={{ - paddingX: theme.spacing(3), - paddingY: theme.spacing(2), - }} - > - <RoomItem {...props} /> - </ListItemButton> - </ListItem> - ); -} - -export function RoomItem({ - id, - roomName, +export function RoomListItem({ + room, communicationType = CommunicationType.DirectMessage, - avatarUrl, - presence, }: RoomListItemProps) { const theme = useTheme(); const { matrixClient, unreadNotificationsPerRoom } = useChatClientContext(); const [lastMessage, setLastMessage] = useState<RoomLastMessage>(); const parsedDate = convertMessageTimestamp(lastMessage?.timestamp); - const unreadNotifications = unreadNotificationsPerRoom[id]; + const unreadNotifications = unreadNotificationsPerRoom[room.roomId]; // TO DO - finish notification feature const disableNotifications = false; const updateRoomLastMessage = useCallback(async () => { - const lastMessage = await getRoomLastMessage(matrixClient, id); + const lastMessage = await getRoomLastMessage(matrixClient, room.roomId); setLastMessage(lastMessage); - }, [id, matrixClient]); + }, [matrixClient, room.roomId]); + + const dmMember = useMemo( + () => (isDMRoom(communicationType) ? room.getAvatarFallbackMember() : null), + [communicationType, room], + ); + + const avatarUrl = useMemo( + () => + dmMember + ? getMemberAvatarUrl(matrixClient, dmMember) + : getRoomAvatarUrl(matrixClient, room), + [dmMember, matrixClient, room], + ); useEffect(() => { void updateRoomLastMessage(); @@ -91,15 +69,15 @@ export function RoomItem({ sx={{ alignItems: "center", width: "100%" }} > <ChatAvatar - name={roomName} + name={room.name} + userId={dmMember?.userId} communicationType={communicationType} - presence={presence} avatarUrl={avatarUrl} /> <Stack sx={{ flex: 1, overflow: "hidden" }}> <Stack direction="row" spacing={0.5} sx={{ alignItems: "center" }}> - <Typography noWrap level="title-md"> - {roomName} + <Typography noWrap level="title-md" sx={{ minWidth: "4ch" }}> + {room.name} </Typography> {disableNotifications && ( <NotificationsOffOutlinedIcon @@ -116,7 +94,6 @@ export function RoomItem({ <Stack sx={{ alignItems: "flex-end", - maxWidth: "4rem", }} > <Typography @@ -124,9 +101,7 @@ export function RoomItem({ textColor="text.secondary" noWrap sx={{ - overflow: "hidden", - textOverflow: "ellipsis", - maxWidth: "4rem", + maxWidth: "5ch", }} > {parsedDate} diff --git a/employee-portal/src/lib/businessModules/chat/components/roomsPanel/RoomsPanel.tsx b/employee-portal/src/lib/businessModules/chat/components/roomsPanel/RoomsPanel.tsx index c4635609b925dda23014ff3df8c56c2e67b2e3ed..e73e8afed5502c26a4b89440ca24888a590ca2d1 100644 --- a/employee-portal/src/lib/businessModules/chat/components/roomsPanel/RoomsPanel.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/roomsPanel/RoomsPanel.tsx @@ -5,25 +5,41 @@ import { Stack } from "@mui/joy"; -import { chatColumnHeaderHeight } from "@/lib/businessModules/chat/components/ChatColumnHeaderWrapper"; import { RoomList } from "@/lib/businessModules/chat/components/roomList/RoomList"; import { RoomsPanelHeader } from "@/lib/businessModules/chat/components/roomsPanel/RoomsPanelHeader"; +import { ChatPanelView } from "@/lib/businessModules/chat/shared/enums"; import { useChatRoomList } from "@/lib/businessModules/chat/shared/hooks/useChatRoomList"; -export function RoomsPanel() { +interface RoomsPanelProps { + setChatPanelView: (viewType: ChatPanelView) => void; + isOpenChatSettings: boolean; + toggleChatSettingsView(): void; +} +export function RoomsPanel({ + setChatPanelView, + isOpenChatSettings, + toggleChatSettingsView, +}: Readonly<RoomsPanelProps>) { const { roomList } = useChatRoomList(); return ( <> {/* TODO - rooms filtering */} - <RoomsPanelHeader /> + <RoomsPanelHeader + setChatPanelView={(viewType) => { + setChatPanelView(viewType); + if (isOpenChatSettings) { + toggleChatSettingsView(); + } + }} + /> <Stack sx={{ - height: `calc(100% - ${chatColumnHeaderHeight})`, + flex: 1, overflowY: "auto", }} > - <RoomList roomList={roomList} /> + <RoomList roomList={roomList} setChatPanelView={setChatPanelView} /> </Stack> </> ); diff --git a/employee-portal/src/lib/businessModules/chat/components/roomsPanel/RoomsPanelHeader.tsx b/employee-portal/src/lib/businessModules/chat/components/roomsPanel/RoomsPanelHeader.tsx index 49fe41711e0147736dd6ca727696e87ed8dadb37..7a53eb3ca4ef52930cf27faff6c3035012bb80a8 100644 --- a/employee-portal/src/lib/businessModules/chat/components/roomsPanel/RoomsPanelHeader.tsx +++ b/employee-portal/src/lib/businessModules/chat/components/roomsPanel/RoomsPanelHeader.tsx @@ -5,22 +5,43 @@ import OpenInNewIcon from "@mui/icons-material/OpenInNew"; import SearchIcon from "@mui/icons-material/Search"; -import { IconButton, Input, Stack } from "@mui/joy"; +import { Dropdown, Input, Menu, MenuButton, MenuItem, Stack } from "@mui/joy"; import { ChatColumnHeaderWrapper } from "@/lib/businessModules/chat/components/ChatColumnHeaderWrapper"; +import { ChatPanelView } from "@/lib/businessModules/chat/shared/enums"; -export function RoomsPanelHeader() { +interface RoomsPanelHeaderProps { + setChatPanelView: (viewType: ChatPanelView) => void; +} +export function RoomsPanelHeader({ + setChatPanelView, +}: Readonly<RoomsPanelHeaderProps>) { return ( <ChatColumnHeaderWrapper> <Stack direction="row" spacing={2}> <Input startDecorator={<SearchIcon />} /> - <IconButton - aria-label="Open new chat window" - variant="solid" - color="primary" - > - <OpenInNewIcon size="sm" /> - </IconButton> + <Dropdown> + <MenuButton + aria-label="Open new chat window" + variant="solid" + color="primary" + sx={{ p: "0.5rem" }} + > + <OpenInNewIcon size="sm" /> + </MenuButton> + <Menu> + <MenuItem + onClick={() => setChatPanelView(ChatPanelView.NewDirectChat)} + > + Direktnachricht + </MenuItem> + <MenuItem + onClick={() => setChatPanelView(ChatPanelView.NewGroupChat)} + > + Gruppe erstellen + </MenuItem> + </Menu> + </Dropdown> </Stack> </ChatColumnHeaderWrapper> ); diff --git a/employee-portal/src/lib/businessModules/chat/components/settingsPanel/SettingsPanel.tsx b/employee-portal/src/lib/businessModules/chat/components/settingsPanel/SettingsPanel.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e0553b165a7da9a38f69bed366d70e57ed2d1458 --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/settingsPanel/SettingsPanel.tsx @@ -0,0 +1,125 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import LogoutOutlinedIcon from "@mui/icons-material/LogoutOutlined"; +import { Box, Stack, Typography } from "@mui/joy"; +import { useState } from "react"; +import { filter } from "remeda"; + +import { GhostButton } from "@/lib/businessModules/chat/components/GhostButton"; +import { GroupChatMember } from "@/lib/businessModules/chat/components/GroupChatMember"; +import { LeaveChatConfirmation } from "@/lib/businessModules/chat/components/LeaveChatConfirmation"; +import { SettingsPanelHeader } from "@/lib/businessModules/chat/components/settingsPanel/SettingsPanelHeader"; +import { + getDepartmentNameFromUserId, + isDMRoom, + isGroupRoom, + leaveRoom, +} from "@/lib/businessModules/chat/shared//utils"; +import { useChatSearchParams } from "@/lib/businessModules/chat/shared/hooks/useChatSearchParams"; +import { useRoomInfo } from "@/lib/businessModules/chat/shared/hooks/useRoomInfo"; + +export interface SettingsPanelProps { + roomId: string; + isOpenChatSettings: boolean; + toggleChatSettingsView(): void; +} + +export function SettingsPanel(props: SettingsPanelProps) { + const roomInfo = useRoomInfo(props.roomId); + const { clearChatParams } = useChatSearchParams(); + const [isOpen, setIsOpen] = useState(false); + + if (!roomInfo) return null; + + const { room, communicationType, allRoomMembers, dmRoomMember, isAdmin } = + roomInfo; + + const sortedMembers = [ + ...filter(allRoomMembers, (x) => x.isRoomCreator), + ...filter(allRoomMembers, (x) => !x.isRoomCreator), + ]; + + function handleLeaveRoomClick() { + setIsOpen(false); + clearChatParams(); + void leaveRoom(roomInfo.matrixClient, room?.roomId); + } + + return ( + <> + <SettingsPanelHeader roomInfo={roomInfo} {...props} /> + <Box + sx={{ + overflowY: "auto", + }} + > + {/* Direct message room content */} + {isDMRoom(communicationType) && ( + <Stack + sx={{ + padding: 3, + borderBottom: "1px solid", + borderColor: "neutral.outlinedBorder", + }} + > + <Typography sx={{ textTransform: "capitalize" }}> + { + getDepartmentNameFromUserId(dmRoomMember?.member.userId) + ?.organisationName + } + </Typography> + </Stack> + )} + + {/* Group room content */} + {isGroupRoom(communicationType) && ( + <Stack + spacing={2} + sx={{ + padding: 3, + overflowY: "auto", + }} + > + {sortedMembers.map(({ member, isRoomCreator }) => { + return ( + <GroupChatMember + key={member.userId} + member={member} + isRoomCreator={isRoomCreator} + isAdmin={isAdmin} + /> + ); + })} + </Stack> + )} + </Box> + <Stack + spacing={1} + sx={{ + padding: 3, + alignItems: "flex-start", + borderTop: isDMRoom(communicationType) ? undefined : "1px solid", + borderColor: "neutral.outlinedBorder", + width: "100%", + }} + > + <GhostButton + startDecorator={<LogoutOutlinedIcon />} + onClick={() => setIsOpen(true)} + > + {isDMRoom(roomInfo.communicationType) + ? "Verlassen" + : "Gruppe verlassen"} + </GhostButton> + </Stack> + <LeaveChatConfirmation + open={isOpen} + onClose={() => setIsOpen(false)} + onConfirm={handleLeaveRoomClick} + /> + </> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/components/settingsPanel/SettingsPanelHeader.tsx b/employee-portal/src/lib/businessModules/chat/components/settingsPanel/SettingsPanelHeader.tsx new file mode 100644 index 0000000000000000000000000000000000000000..3a10be6e2db1d8a409e057a4583a3f77e8837909 --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/components/settingsPanel/SettingsPanelHeader.tsx @@ -0,0 +1,45 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import CloseIcon from "@mui/icons-material/Close"; +import { IconButton, Stack } from "@mui/joy"; + +import { ChatColumnHeaderWrapper } from "@/lib/businessModules/chat/components/ChatColumnHeaderWrapper"; +import { ChatHeader } from "@/lib/businessModules/chat/components/ChatHeader"; +import { SettingsPanelProps } from "@/lib/businessModules/chat/components/settingsPanel/SettingsPanel"; +import { RoomInfo } from "@/lib/businessModules/chat/shared/hooks/useRoomInfo"; + +interface SettingsPanelHeaderProps extends SettingsPanelProps { + roomInfo: RoomInfo; +} + +export function SettingsPanelHeader({ + toggleChatSettingsView, + roomInfo, +}: SettingsPanelHeaderProps) { + return ( + <ChatColumnHeaderWrapper> + <Stack + direction="row" + spacing={1} + sx={{ + alignItems: "center", + }} + > + <ChatHeader {...roomInfo} variant="settings" /> + <IconButton + variant="outlined" + aria-label="close sidebar" + onClick={toggleChatSettingsView} + sx={{ + borderColor: "primary.outlinedBorder", + }} + > + <CloseIcon color="primary" /> + </IconButton> + </Stack> + </ChatColumnHeaderWrapper> + ); +} diff --git a/employee-portal/src/lib/businessModules/chat/shared/ChatClientProvider.tsx b/employee-portal/src/lib/businessModules/chat/shared/ChatClientProvider.tsx index 437a156a5aeebe6d0d1f9a423f165bc33fae24cd..33332e5ba2667e5346a48cf17dd5e0d19f658123 100644 --- a/employee-portal/src/lib/businessModules/chat/shared/ChatClientProvider.tsx +++ b/employee-portal/src/lib/businessModules/chat/shared/ChatClientProvider.tsx @@ -32,8 +32,8 @@ import { useChatLifecycle } from "@/lib/businessModules/chat/shared/hooks/useCha import { usePresence } from "@/lib/businessModules/chat/shared/hooks/usePresence"; import { routes } from "@/lib/businessModules/chat/shared/routes"; import { - Presence, RoomEventDetails, + UsersPresence, isMessageTypeWithBody, } from "@/lib/businessModules/chat/shared/types"; import { shouldShowMessageTeaser } from "@/lib/businessModules/chat/shared/utils"; @@ -44,7 +44,7 @@ export interface ChatClientContextType { clientState: ClientState; setClientState: Dispatch<SetStateAction<ClientState>>; unreadNotificationsPerRoom: Record<string, number>; - usersPresence: Record<string, Presence>; + usersPresence: UsersPresence; } export const ChatClientContext = createContext<ChatClientContextType | null>( diff --git a/employee-portal/src/lib/businessModules/chat/shared/enums.ts b/employee-portal/src/lib/businessModules/chat/shared/enums.ts index e2927fadc105265bb2cfbc5978fbe9b7d3613bba..d49580d4b2c021aa9eab2f12698f3a0d2bbd0eb3 100644 --- a/employee-portal/src/lib/businessModules/chat/shared/enums.ts +++ b/employee-portal/src/lib/businessModules/chat/shared/enums.ts @@ -20,3 +20,10 @@ export enum CommunicationType { DirectMessage = "DIRECT_MESSAGE", PublicRoom = "PUBLIC_ROOM", } + +export enum ChatPanelView { + NoChatSelected = "NO_CHAT_SELECTED", + NewDirectChat = "NEW_DIRECT_CHAT", + NewGroupChat = "NEW_GROUP_CHAT", + ChatMessages = "CHAT_MESSAGES", +} diff --git a/employee-portal/src/lib/businessModules/chat/shared/hooks/useChatLifecycle.tsx b/employee-portal/src/lib/businessModules/chat/shared/hooks/useChatLifecycle.tsx index 284651f0c0f7b20d2375a212617778b83c7c6cc4..9184a2cc111436adeafad826b9c28344e76001ee 100644 --- a/employee-portal/src/lib/businessModules/chat/shared/hooks/useChatLifecycle.tsx +++ b/employee-portal/src/lib/businessModules/chat/shared/hooks/useChatLifecycle.tsx @@ -33,7 +33,10 @@ import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; import { ClientState } from "@/lib/businessModules/chat/shared/enums"; import { logger } from "@/lib/businessModules/chat/shared/helpers"; import { IStoredCredentials } from "@/lib/businessModules/chat/shared/types"; -import { validateChatUsername } from "@/lib/businessModules/chat/shared/utils"; +import { + delayed, + validateChatUsername, +} from "@/lib/businessModules/chat/shared/utils"; const MAX_ATTEMPTS = 3; @@ -134,10 +137,15 @@ export function useChatLifecycle( logger.info("INIT RUST CRYPTO"); - await matrixClient.current.initRustCrypto({ - storageKey: rustCryptoStoreArgs.rustCryptoStoreKey, - storagePassword: rustCryptoStoreArgs.rustCryptoStorePassword, - }); + try { + await matrixClient.current.initRustCrypto({ + storageKey: rustCryptoStoreArgs.rustCryptoStoreKey, + storagePassword: rustCryptoStoreArgs.rustCryptoStorePassword, + }); + } catch (error) { + logger.error("Init Rust crypto error", error); + await restartChat(); + } setClientState(ClientState.ClientCreated); @@ -146,7 +154,7 @@ export function useChatLifecycle( await matrixClient.current.startClient({ initialSyncLimit: 10, }); - }, [baseUrl, credentials, matrixClient, setClientState]); + }, [baseUrl, credentials, matrixClient, restartChat, setClientState]); /** * Handle matrix encryption @@ -154,14 +162,18 @@ export function useChatLifecycle( const handleChatEncryption = useCallback(async () => { logger.info("HANDLE CHAT ENCRYPTION"); try { - const { backupInfo, has4S } = await fetchBackupInfo(matrixClient.current); + let res = await fetchBackupInfo(matrixClient.current); + + if (!res.has4S && res.backupInfo) { + res = await delayed(() => fetchBackupInfo(matrixClient.current), 300); + } - if (!has4S || !backupInfo) { + if (!res.has4S || !res.backupInfo) { setClientState(ClientState.CreateBackupKey); } else { const restored = await restoreKeyBackupWithCache( matrixClient.current, - backupInfo, + res.backupInfo, ); if (!restored) { diff --git a/employee-portal/src/lib/businessModules/chat/shared/hooks/useChatSearchParams.ts b/employee-portal/src/lib/businessModules/chat/shared/hooks/useChatSearchParams.ts new file mode 100644 index 0000000000000000000000000000000000000000..fd6c27ccaa2b46568c720f050eba07075ea7d81a --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/shared/hooks/useChatSearchParams.ts @@ -0,0 +1,82 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useSearchParams } from "next/navigation"; +import { useCallback } from "react"; + +import { chatSearchParamNames } from "@/lib/businessModules/chat/shared/constants"; +import { useReplaceSearchParams } from "@/lib/shared/hooks/searchParams/useReplaceSearchParams"; + +export function useChatSearchParams() { + const searchParams = useSearchParams(); + const replaceSearchParams = useReplaceSearchParams(); + const selectedRoomId = searchParams.get(chatSearchParamNames.roomId) ?? ""; + const selectedUserId = searchParams.get(chatSearchParamNames.userId) ?? ""; + + const setRoomIdParam = useCallback( + (roomId: string) => { + replaceSearchParams([ + { + name: chatSearchParamNames.roomId, + value: roomId, + }, + ]); + }, + [replaceSearchParams], + ); + + const clearRoomIdParam = useCallback(() => { + replaceSearchParams([ + { + name: chatSearchParamNames.roomId, + value: "", + }, + ]); + }, [replaceSearchParams]); + + const setUserIdParam = useCallback( + (userId: string) => { + replaceSearchParams([ + { + name: chatSearchParamNames.userId, + value: userId, + }, + ]); + }, + [replaceSearchParams], + ); + + const clearUserIdParam = useCallback(() => { + replaceSearchParams([ + { + name: chatSearchParamNames.userId, + value: "", + }, + ]); + }, [replaceSearchParams]); + + const clearChatParams = useCallback(() => { + replaceSearchParams([ + { + name: chatSearchParamNames.userId, + value: "", + }, + { + name: chatSearchParamNames.roomId, + value: "", + }, + ]); + }, [replaceSearchParams]); + + return { + selectedRoomId, + selectedUserId, + setRoomIdParam, + setUserIdParam, + clearRoomIdParam, + clearUserIdParam, + clearChatParams, + }; +} diff --git a/employee-portal/src/lib/businessModules/chat/shared/hooks/useChatUtils.tsx b/employee-portal/src/lib/businessModules/chat/shared/hooks/useChatUtils.tsx deleted file mode 100644 index fd96b7974f0e0fa1e89fc30bb82d70882b288182..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/shared/hooks/useChatUtils.tsx +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { EventType, HistoryVisibility } from "matrix-js-sdk/lib/matrix"; -import { isNullish, isString } from "remeda"; - -import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; -import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; -import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; -import { RoomWithCommunicationType } from "@/lib/businessModules/chat/shared/types"; - -export function useChatUtils() { - const { configuration } = useChat(); - const { matrixClient } = useChatClientContext(); - const matrixServerUrl = configuration.MATRIX_SERVER_URL; - - async function leaveRoom(roomId: string) { - try { - await matrixClient.leave(roomId); - } catch {} - } - - function getUser(userId: string) { - return matrixClient.getUser(userId); - } - - function getImageUrl(url: string | undefined) { - if (!url) { - return null; - } - const isMxc = new URL(url).protocol === "mxc:"; - return isMxc ? matrixClient.mxcUrlToHttp(url) : url; - } - - function getRoomAvatar(room: RoomWithCommunicationType | null | undefined) { - if (isNullish(room) || !isString(matrixServerUrl)) { - return; - } - if (room.communicationType === CommunicationType.PublicRoom) { - const roomAvatarUrl = - room.room.getAvatarUrl(matrixServerUrl, 40, 40, "scale", true) ?? - undefined; - - const imageUrl = getImageUrl(roomAvatarUrl ?? undefined) ?? undefined; - return roomAvatarUrl ? imageUrl : undefined; - } - - const directMessageAvatar = room.room.getAvatarFallbackMember(); - if (!directMessageAvatar) { - return undefined; - } - const avatarUrl = directMessageAvatar?.getAvatarUrl( - matrixServerUrl, - 40, - 40, - "scale", - true, - false, - ); - const imageUrl = getImageUrl(avatarUrl ?? undefined) ?? undefined; - return avatarUrl ? imageUrl : undefined; - } - - function invite(roomId: string, userId: string) { - return matrixClient.invite(roomId, userId); - } - - // Change `m.room.history_visibility` - async function handleChangeHistoryVisibility( - roomId: string, - newHistoryVisibility: HistoryVisibility, - ) { - return matrixClient.sendStateEvent( - roomId, - EventType.RoomHistoryVisibility, - { - history_visibility: newHistoryVisibility, - }, - ); - } - - return { - leaveRoom, - getRoomAvatar, - getImageUrl, - getUser, - invite, - handleChangeHistoryVisibility, - }; -} diff --git a/employee-portal/src/lib/businessModules/chat/shared/hooks/useCreateNewChat.tsx b/employee-portal/src/lib/businessModules/chat/shared/hooks/useCreateNewChat.tsx index cb66ab62b252c2352f9bdb9330ba2c3649138001..0b8df151cf11e259754bdbfc4ef43739c9f905bc 100644 --- a/employee-portal/src/lib/businessModules/chat/shared/hooks/useCreateNewChat.tsx +++ b/employee-portal/src/lib/businessModules/chat/shared/hooks/useCreateNewChat.tsx @@ -12,7 +12,7 @@ import { import { useCallback } from "react"; import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; -import { useSelectedRoomId } from "@/lib/businessModules/chat/shared/hooks/useSelectedRoomId"; +import { useChatSearchParams } from "@/lib/businessModules/chat/shared/hooks/useChatSearchParams"; import { findDirectChat, getRoomNameAndCommunicationType, @@ -39,7 +39,7 @@ const createRoomInitialState = [ export function useCreateNewChat() { const { matrixClient } = useChatClientContext(); - const { setSelectedRoomId } = useSelectedRoomId(); + const { setRoomIdParam } = useChatSearchParams(); const createNewDirectMessage = useCallback( async ({ invite }: ICreateRoomOpts) => { @@ -55,7 +55,7 @@ export function useCreateNewChat() { const DMUser = invite?.[0]; const DMRoom = findDirectChat({ chatRooms, userId: DMUser }); if (DMRoom) { - setSelectedRoomId(DMRoom.room.roomId); + setRoomIdParam(DMRoom.room.roomId); return DMRoom.room.roomId; } } @@ -83,10 +83,11 @@ export function useCreateNewChat() { : []) as ICreateRoomStateEvent[]), ], }); - setSelectedRoomId(newRoom.room_id); + setRoomIdParam(newRoom.room_id); + return newRoom.room_id; } catch {} }, - [matrixClient, setSelectedRoomId], + [matrixClient, setRoomIdParam], ); const createNewChatRoom = useCallback( async ({ invite, name }: ICreateRoomOpts) => { @@ -107,10 +108,24 @@ export function useCreateNewChat() { }, ], }); - setSelectedRoomId(newRoom.room_id); + setRoomIdParam(newRoom.room_id); + return newRoom.room_id; } catch {} }, - [matrixClient, setSelectedRoomId], + [matrixClient, setRoomIdParam], ); - return { createNewChatRoom, createNewDirectMessage }; + const findExisingRoom = useCallback( + (userId: string) => { + const joinedRooms = matrixClient + .getRooms() + .filter((room) => room.getMyMembership() === "join"); + const chatRooms = joinedRooms.map((room) => + getRoomNameAndCommunicationType(room), + ); + + return findDirectChat({ chatRooms, userId }); + }, + [matrixClient], + ); + return { createNewChatRoom, createNewDirectMessage, findExisingRoom }; } diff --git a/employee-portal/src/lib/businessModules/chat/shared/hooks/usePresence.tsx b/employee-portal/src/lib/businessModules/chat/shared/hooks/usePresence.tsx index 67b5280a4cc2229ce669181bddd298c17e5a5c36..c867e2442730b2b1d0ffccedd838c2fcdf051855 100644 --- a/employee-portal/src/lib/businessModules/chat/shared/hooks/usePresence.tsx +++ b/employee-portal/src/lib/businessModules/chat/shared/hooks/usePresence.tsx @@ -14,7 +14,10 @@ import { useEffect, useState } from "react"; import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; import { ClientState } from "@/lib/businessModules/chat/shared/enums"; -import { Presence } from "@/lib/businessModules/chat/shared/types"; +import { + Presence, + UsersPresence, +} from "@/lib/businessModules/chat/shared/types"; export function usePresence( matrixClient: MatrixClient, @@ -23,16 +26,14 @@ export function usePresence( const { userSettings: { sharePresence }, } = useChat(); - const [usersPresence, setUsersPresence] = useState<Record<string, Presence>>( - {}, - ); + const [usersPresence, setUsersPresence] = useState<UsersPresence>({}); useEffect(() => { matrixClient.once(ClientEvent.Sync, function (state) { if (state === SyncState.Prepared) { const users = matrixClient.getUsers(); const statuses = Object.fromEntries( users.map((user) => [user.userId, user.presence]), - ) as Record<string, Presence>; + ) as UsersPresence; setUsersPresence(statuses); } }); diff --git a/employee-portal/src/lib/businessModules/chat/shared/hooks/useReadConfirmation.tsx b/employee-portal/src/lib/businessModules/chat/shared/hooks/useReadConfirmation.tsx index 5238e08180cda50e878a6789b27aa608942a9535..6f91c638c14488763fb6d50d9e181f07cff7573b 100644 --- a/employee-portal/src/lib/businessModules/chat/shared/hooks/useReadConfirmation.tsx +++ b/employee-portal/src/lib/businessModules/chat/shared/hooks/useReadConfirmation.tsx @@ -8,7 +8,7 @@ import { useEffect, useState } from "react"; import { isObjectType } from "remeda"; import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; -import { useSelectedRoomId } from "@/lib/businessModules/chat/shared/hooks/useSelectedRoomId"; +import { useChatSearchParams } from "@/lib/businessModules/chat/shared/hooks/useChatSearchParams"; import { ReadConfirmationsPerRoom, ReadConfirmationsPerUser, @@ -25,7 +25,7 @@ export function useReadConfirmation(showReadConfirmation: boolean) { useState<ReadConfirmationsPerRoom>({}); const { matrixClient } = useChatClientContext(); const isFocused = useWindowFocus(); - const { selectedRoomId } = useSelectedRoomId(); + const { selectedRoomId } = useChatSearchParams(); useEffect(() => { if (!isFocused) return; diff --git a/employee-portal/src/lib/businessModules/chat/shared/hooks/useRoomInfo.ts b/employee-portal/src/lib/businessModules/chat/shared/hooks/useRoomInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..bdb84afe3bedad48a7ff9210264d9ce608fba1c5 --- /dev/null +++ b/employee-portal/src/lib/businessModules/chat/shared/hooks/useRoomInfo.ts @@ -0,0 +1,85 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { Direction, EventType, MatrixClient, Room } from "matrix-js-sdk"; +import { useMemo } from "react"; +import { isStrictEqual } from "remeda"; + +import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; +import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; +import { AllRoomMembers } from "@/lib/businessModules/chat/shared/types"; +import { + getMemberAvatarUrl, + getRoomAvatarUrl, + getRoomNameAndCommunicationType, + isDMRoom, +} from "@/lib/businessModules/chat/shared/utils"; + +export interface RoomInfo { + room: Room | null; + roomCreator?: string; + communicationType?: CommunicationType; + roomAvatarUrl: string | null; + allRoomMembers: AllRoomMembers[]; + roomMembers: AllRoomMembers[]; + dmRoomMember: AllRoomMembers | undefined; + isAdmin: boolean; + matrixClient: MatrixClient; +} + +export function useRoomInfo(roomId: string): RoomInfo { + const { matrixClient } = useChatClientContext(); + + const room = matrixClient.getRoom(roomId); + const rct = useMemo( + () => (room ? getRoomNameAndCommunicationType(room) : undefined), + [room], + ); + + const roomCreator = useMemo( + () => + room + ?.getLiveTimeline() + .getState(Direction.Forward) + ?.getStateEvents(EventType.RoomCreate)?.[0]?.event.sender, + [room], + ); + + const allRoomMembers = + room?.getMembers().map((member) => ({ + member, + isRoomCreator: isStrictEqual(member.userId, roomCreator), + })) ?? []; + + const roomMembers = allRoomMembers?.filter( + ({ member }) => !isStrictEqual(member.userId, room?.myUserId), + ); + + const dmRoomMember = isDMRoom(rct?.communicationType) + ? roomMembers?.[0] + : undefined; + + const roomAvatarUrl = useMemo( + () => + isDMRoom(rct?.communicationType) + ? getMemberAvatarUrl(matrixClient, dmRoomMember?.member) + : getRoomAvatarUrl(matrixClient, room), + [dmRoomMember?.member, matrixClient, rct?.communicationType, room], + ); + + const isAdmin = isStrictEqual(matrixClient.getUserId(), roomCreator); + + return { + room, + roomCreator, + communicationType: rct?.communicationType, + roomAvatarUrl, + roomMembers, + allRoomMembers, + dmRoomMember, + isAdmin, + matrixClient, + }; +} diff --git a/employee-portal/src/lib/businessModules/chat/shared/hooks/useRoomMessages.tsx b/employee-portal/src/lib/businessModules/chat/shared/hooks/useRoomMessages.tsx index 8107b6d7c570c8c413703a1a805cdea806a007bb..207169aece0c567dca0488729ba97f92748b4ad9 100644 --- a/employee-portal/src/lib/businessModules/chat/shared/hooks/useRoomMessages.tsx +++ b/employee-portal/src/lib/businessModules/chat/shared/hooks/useRoomMessages.tsx @@ -15,7 +15,7 @@ import { useCallback, useEffect, useState } from "react"; import { useChatClientContext } from "@/lib/businessModules/chat/shared/ChatClientProvider"; import { ClientState } from "@/lib/businessModules/chat/shared/enums"; -import { useSelectedRoomId } from "@/lib/businessModules/chat/shared/hooks/useSelectedRoomId"; +import { useChatSearchParams } from "@/lib/businessModules/chat/shared/hooks/useChatSearchParams"; import { Message, RoomEventDetails, @@ -26,7 +26,7 @@ import { export function useRoomMessages() { const [messages, setMessages] = useState<Record<string, Message[]>>({}); const [canPaginate, setCanPaginate] = useState(true); - const { selectedRoomId } = useSelectedRoomId(); + const { selectedRoomId } = useChatSearchParams(); const { matrixClient, clientState } = useChatClientContext(); const messagesLimit = 10; const [isLoading, setIsLoading] = useState(false); diff --git a/employee-portal/src/lib/businessModules/chat/shared/hooks/useSelectedRoomId.ts b/employee-portal/src/lib/businessModules/chat/shared/hooks/useSelectedRoomId.ts deleted file mode 100644 index e2d177bf430454c377431f1c7e488b38d17e6abb..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/chat/shared/hooks/useSelectedRoomId.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { useSearchParams } from "next/navigation"; -import { useCallback } from "react"; - -import { chatSearchParamNames } from "@/lib/businessModules/chat/shared/constants"; -import { useReplaceSearchParams } from "@/lib/shared/hooks/searchParams/useReplaceSearchParams"; - -export function useSelectedRoomId() { - const searchParams = useSearchParams(); - const replaceSearchParams = useReplaceSearchParams(); - const selectedRoomId = searchParams.get(chatSearchParamNames.roomId) ?? ""; - - const setSelectedRoomId = useCallback( - (roomId: string) => { - if (!roomId) { - return; - } - - replaceSearchParams([ - { - name: chatSearchParamNames.roomId, - value: roomId, - }, - { - name: chatSearchParamNames.userId, - value: "", - }, - ]); - }, - [replaceSearchParams], - ); - - return { - selectedRoomId, - setSelectedRoomId, - }; -} diff --git a/employee-portal/src/lib/businessModules/chat/shared/types.ts b/employee-portal/src/lib/businessModules/chat/shared/types.ts index 7da2134ea37e9948c68d4b94c1ae8c7e62e05411..a378b3b4208400239594bde9bf27e5530bcec789 100644 --- a/employee-portal/src/lib/businessModules/chat/shared/types.ts +++ b/employee-portal/src/lib/businessModules/chat/shared/types.ts @@ -9,6 +9,7 @@ import { IPresenceOpts, MatrixEvent, Room, + RoomMember, User, } from "matrix-js-sdk/lib/matrix"; import { isEmpty, isObjectType, isString } from "remeda"; @@ -49,6 +50,7 @@ export interface CreateRoomOptions { } export type Presence = IPresenceOpts["presence"]; +export type UsersPresence = Record<string, Presence>; export type ReadConfirmationsPerUser = Record< string, @@ -71,11 +73,7 @@ interface MessageType { export function isMessageType( messageContent: unknown, ): messageContent is MessageType { - return ( - isObjectType(messageContent) && - "body" in messageContent && - "m.mentions" in messageContent - ); + return isObjectType(messageContent) && "body" in messageContent; } export function isMessageTypeWithBody( @@ -125,8 +123,7 @@ export interface RoomLastMessage { mentions: string[]; } -export interface RoomUserPresence { - userId: string; - name: string; - presence?: Presence; +export interface AllRoomMembers { + member: RoomMember; + isRoomCreator: boolean; } diff --git a/employee-portal/src/lib/businessModules/chat/shared/utils.ts b/employee-portal/src/lib/businessModules/chat/shared/utils.ts index 14d37b74aebd630c1603d456e939ca5c9aed7444..4fc7dc5d3ae62ce01c2cd59907539cc5ad2f08ea 100644 --- a/employee-portal/src/lib/businessModules/chat/shared/utils.ts +++ b/employee-portal/src/lib/businessModules/chat/shared/utils.ts @@ -3,16 +3,29 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { addMilliseconds, format, isToday } from "date-fns"; +import { + addMilliseconds, + format, + isSameDay, + isSameWeek, + isSameYear, + isThisWeek, + isThisYear, + isToday, + isYesterday, + startOfDay, +} from "date-fns"; +import { de } from "date-fns/locale"; import { EventTimeline, MatrixClient, MatrixEvent, ReceiptType, Room, + RoomMember, User, } from "matrix-js-sdk/lib/matrix"; -import { isEmpty, isString, last } from "remeda"; +import { isEmpty, isStrictEqual, isString, last } from "remeda"; import { CommunicationType } from "@/lib/businessModules/chat/shared/enums"; import { @@ -52,12 +65,7 @@ export function getRoomNameAndCommunicationType( const type = room.getDMInviter() ? "directMessage" : "room"; if (type === "directMessage") { - return { - room: Object.assign(room, { - name: room.name.replace(/@(\w+):.+/, "$1"), - }), - communicationType: CommunicationType.DirectMessage, - }; + return { room, communicationType: CommunicationType.DirectMessage }; } const allMembers = room @@ -67,7 +75,16 @@ export function getRoomNameAndCommunicationType( // These are the direct chats that you invited someone to if (type === "room" && allMembers?.length && allMembers.length <= 2) { - if (allMembers?.some((m) => m.getDMInviter())) { + const someDMInviter = allMembers?.some((m) => m.getDMInviter()); + const otherMember = allMembers.find( + (m) => !isStrictEqual(m.userId, room.myUserId), + ); + const isRoomNameAndOtherMemberEqual = isStrictEqual( + otherMember?.name, + room.name, + ); + + if (someDMInviter || isRoomNameAndOtherMemberEqual) { return { room, communicationType: CommunicationType.DirectMessage }; } } @@ -81,6 +98,16 @@ export function getDirectMessageMember(room: RoomWithCommunicationType) { return room.room.getAvatarFallbackMember(); } +export function getDMMemberInfo( + room: Room, + communicationType: CommunicationType, +) { + if (communicationType === CommunicationType.PublicRoom) { + return; + } + return room.getAvatarFallbackMember(); +} + export function formatUserReceipts( userReceipts: ReadConfirmationsPerUser | undefined, ): Record<string, string[]> | undefined { @@ -292,8 +319,122 @@ export function convertMessageTimestamp(timestamp?: Date | null) { if (!timestamp) return ""; if (isToday(timestamp)) { - return format(timestamp, "HH:MM"); + return format(timestamp, "hh:mm"); } return format(timestamp, "MM/dd"); } + +export function getDayLabel(date: Date): string { + const localDate = startOfDay(date); + if (isToday(localDate)) { + return "Heute"; + } + if (isYesterday(localDate)) { + return "Gestern"; + } + if (isThisWeek(localDate, { weekStartsOn: 1 })) { + return format(localDate, "EEEE", { locale: de }); + } + if (isThisYear(localDate)) { + return format(localDate, "MMMM d"); + } + return format(localDate, "MMMM d, yyyy"); +} + +export function formatDateForChat(date: Date): string { + const currentTime = new Date(); + if (isSameDay(currentTime, date)) { + return "HH:mm"; + } + if (isYesterday(date)) { + return `Gestern ${format(date, "HH:mm", { locale: de })}`; + } + if (isSameWeek(currentTime, date, { weekStartsOn: 1 })) { + return format(date, "EEEE HH:mm", { locale: de }); + } + if (isSameYear(currentTime, date)) { + return format(date, "dd.MM HH:mm"); + } + return format(date, "dd.MM.YY HH:mm"); +} + +// TODO: fix mapping of synapse server name to appropriate health department +export function mapToDepartmentName( + serverName: string | undefined, +): string | undefined { + if (serverName === "synapse.local.dev") { + return "Gesundheitsamt Frankfurt"; + } +} + +export function getDepartmentNameFromUserId(userId?: string) { + if (!userId) return; + + const splittedName = userId.split(":"); + return { + username: splittedName[0], + organisationName: splittedName[1]?.replaceAll(".", " "), + }; +} + +export function isGroupRoom(communicationType?: CommunicationType) { + return communicationType === CommunicationType.PublicRoom; +} + +export function isDMRoom(communicationType?: CommunicationType) { + return communicationType === CommunicationType.DirectMessage; +} + +export function delayed<T>(fn: () => T, delay: number): Promise<T> { + return new Promise((resolve) => { + setTimeout(() => { + resolve(fn()); + }, delay); + }); +} + +function getImageUrl(matrixClient: MatrixClient, url: string | null) { + if (!url) return null; + + const isMxc = new URL(url).protocol === "mxc:"; + return isMxc ? matrixClient.mxcUrlToHttp(url) : url; +} + +export function getRoomAvatarUrl( + matrixClient: MatrixClient, + room: Room | null, +) { + if (!room) return null; + const homeserverUrl = matrixClient.getHomeserverUrl(); + const roomAvatarUrl = room.getAvatarUrl(homeserverUrl, 40, 40, "scale", true); + + const imageUrl = getImageUrl(matrixClient, roomAvatarUrl); + return imageUrl; +} + +export function getMemberAvatarUrl( + matrixClient: MatrixClient, + member?: RoomMember, +) { + if (!member) return null; + const homeserverUrl = matrixClient.getHomeserverUrl(); + const memberAvatarUrl = member.getAvatarUrl( + homeserverUrl, + 40, + 40, + "scale", + true, + false, + ); + + const imageUrl = getImageUrl(matrixClient, memberAvatarUrl); + return imageUrl; +} + +export async function leaveRoom(matrixClient: MatrixClient, roomId?: string) { + if (!roomId) return; + try { + await matrixClient.leave(roomId); + } catch {} +} diff --git a/employee-portal/src/lib/businessModules/inspection/api/clients.ts b/employee-portal/src/lib/businessModules/inspection/api/clients.ts index ba41d991070781f76c0bbe1e8bd72d3cc4f1a8d6..5ee306af083dea04d229811ffc4ea81898e23d79 100644 --- a/employee-portal/src/lib/businessModules/inspection/api/clients.ts +++ b/employee-portal/src/lib/businessModules/inspection/api/clients.ts @@ -5,6 +5,7 @@ import { ApprovalRequestApi, + ArchivingApi, ChecklistApi, ChecklistDefinitionApi, ChecklistDefinitionCentralRepoApi, @@ -140,3 +141,8 @@ export function useInspectionFeatureTogglesApi() { const configuration = useConfiguration(); return new InspectionFeatureTogglesApi(configuration); } + +export function useArchivingApi() { + const configuration = useConfiguration(); + return new ArchivingApi(configuration); +} diff --git a/employee-portal/src/lib/businessModules/inspection/api/mutations/archiving.ts b/employee-portal/src/lib/businessModules/inspection/api/mutations/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..7bd25ae217fcf72ce7bddd22064c6c3b2ea491da --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/api/mutations/archiving.ts @@ -0,0 +1,18 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useArchivingApi } from "@/lib/businessModules/inspection/api/clients"; +import { + useBulkUpdateProceduresArchivingRelevanceTemplate, + useExportRelevantProceduresTemplate, +} from "@/lib/shared/api/mutations/archiving"; + +export function useBulkUpdateProceduresArchivingRelevance() { + return useBulkUpdateProceduresArchivingRelevanceTemplate(useArchivingApi); +} + +export function useExportRelevantProcedures() { + return useExportRelevantProceduresTemplate(useArchivingApi); +} diff --git a/employee-portal/src/lib/businessModules/inspection/api/mutations/checklistDefinition.ts b/employee-portal/src/lib/businessModules/inspection/api/mutations/checklistDefinition.ts index ae286337d484a7b819da8377346a1d1234364de7..75e5e44c2c23abb0ec2c9646671e17aa0a20a683 100644 --- a/employee-portal/src/lib/businessModules/inspection/api/mutations/checklistDefinition.ts +++ b/employee-portal/src/lib/businessModules/inspection/api/mutations/checklistDefinition.ts @@ -5,9 +5,10 @@ import { AddChecklistDefinitionToCentralRepoRequest, - ApiAddChecklistDefinitionVersionRequest, ApiCLContext, ApiChecklistDefinitionFromCentralRepoUpdateRequest, + ApiChecklistDefinitionVersion, + ApiChecklistDefinitionVersionRequest, ApiCreateNewChecklistDefinitionRequest, DeleteChecklistDefinitionFromCentralRepoRequest, UpdateChecklistDefinitionToCentralRepoRequest, @@ -44,6 +45,7 @@ export function useCreateChecklistDefinition() { isCoreChecklist: cldVersion.isCoreChecklist, isExpandable: cldVersion.context.expandable, deleted: cldVersion.context.deleted, + published: cldVersion.context.published, }; return await checklistDefinitionApi.createNewChecklistDefinition( @@ -53,7 +55,7 @@ export function useCreateChecklistDefinition() { }); } -export function useUpdateChecklistDefinition() { +export function useAddChecklistDefinitionVersion() { const checklistDefinitionApi = useChecklistDefinitionApi(); return useHandledMutation({ mutationFn: async ({ @@ -61,14 +63,17 @@ export function useUpdateChecklistDefinition() { cldVersion, }: { defId: string; - cldVersion: FormChecklistDefinitionVersion; + cldVersion: + | FormChecklistDefinitionVersion + | ApiChecklistDefinitionVersion; }) => { - const createdChecklist: ApiAddChecklistDefinitionVersionRequest = { + const createdChecklist: ApiChecklistDefinitionVersionRequest = { description: cldVersion.context.description, name: cldVersion.context.name, sections: cldVersion.context.sections, isExpandable: cldVersion.context.expandable, deleted: cldVersion.context.deleted, + published: cldVersion.context.published, }; return await checklistDefinitionApi.addChecklistDefinitionVersion( @@ -79,6 +84,35 @@ export function useUpdateChecklistDefinition() { }); } +export function useEditDraftChecklistDefinitionVersion() { + const checklistDefinitionApi = useChecklistDefinitionApi(); + return useHandledMutation({ + mutationFn: async ({ + versionId, + cldVersion, + }: { + versionId: string; + cldVersion: + | FormChecklistDefinitionVersion + | ApiChecklistDefinitionVersion; + }) => { + const request: ApiChecklistDefinitionVersionRequest = { + description: cldVersion.context.description, + name: cldVersion.context.name, + sections: cldVersion.context.sections, + isExpandable: cldVersion.context.expandable, + deleted: cldVersion.context.deleted, + published: cldVersion.context.published, + }; + + return await checklistDefinitionApi.editDraftChecklistDefinitionVersion( + versionId, + request, + ); + }, + }); +} + export function useAddChecklistDefinitionToCentralRepo() { const repoApi = useChecklistDefinitionCentralRepoApi(); const snackbar = useSnackbar(); diff --git a/employee-portal/src/lib/businessModules/inspection/api/queries/apiQueryKeys.ts b/employee-portal/src/lib/businessModules/inspection/api/queries/apiQueryKeys.ts index 476683a94da7f50124197c441548e06a28869129..1ad865161aacd075f186e96c3e8d12e85253b598 100644 --- a/employee-portal/src/lib/businessModules/inspection/api/queries/apiQueryKeys.ts +++ b/employee-portal/src/lib/businessModules/inspection/api/queries/apiQueryKeys.ts @@ -88,3 +88,7 @@ export const packlistDefinitionApiQueryKey = queryKeyFactory( export const inspectionFeatureTogglesApiQueryKey = queryKeyFactory( apiQueryKey(["featureTogglesApi"]), ); + +export const archivingApiQueryKey = queryKeyFactory( + apiQueryKey(["archivingApi"]), +); diff --git a/employee-portal/src/lib/businessModules/inspection/api/queries/archiving.ts b/employee-portal/src/lib/businessModules/inspection/api/queries/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..8542230cf588b63504650e34bb7f0a71971187ff --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/api/queries/archiving.ts @@ -0,0 +1,44 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + GetArchivableProceduresRequest, + GetRelevantArchivableProceduresRequest, +} from "@eshg/employee-portal-api/businessProcedures"; + +import { useArchivingApi } from "@/lib/businessModules/inspection/api/clients"; +import { archivingApiQueryKey } from "@/lib/businessModules/inspection/api/queries/apiQueryKeys"; +import { + useGetArchivableProceduresTemplate, + useGetArchivingConfigurationTemplate, + useGetRelevantArchivableProceduresTemplate, +} from "@/lib/shared/api/queries/archiving"; + +export function useGetArchivingConfiguration() { + return useGetArchivingConfigurationTemplate( + useArchivingApi, + archivingApiQueryKey, + ); +} + +export function useGetArchivableProcedures( + request: GetArchivableProceduresRequest, +) { + return useGetArchivableProceduresTemplate( + useArchivingApi, + archivingApiQueryKey, + request, + ); +} + +export function useGetRelevantArchivableProcedures( + request: GetRelevantArchivableProceduresRequest, +) { + return useGetRelevantArchivableProceduresTemplate( + useArchivingApi, + archivingApiQueryKey, + request, + ); +} diff --git a/employee-portal/src/lib/businessModules/inspection/api/queries/facility.ts b/employee-portal/src/lib/businessModules/inspection/api/queries/facility.ts index b1e7b75f55d8224a425640aaa7fbb62aa0241dee..212cbe236ccfe0a7266564755dce93c4892f3bda 100644 --- a/employee-portal/src/lib/businessModules/inspection/api/queries/facility.ts +++ b/employee-portal/src/lib/businessModules/inspection/api/queries/facility.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { GetPendingFacilitiesRequest } from "@eshg/employee-portal-api/inspection"; import { unwrapRawResponse } from "@eshg/lib-portal/api/unwrapRawResponse"; import { useSuspenseQuery } from "@tanstack/react-query"; @@ -21,16 +22,7 @@ export function useGetFacility(facilityId: string) { export function useGetPendingFacilities(filters: PendingFacilitiesFilters) { const facilityApi = useFacilityApi(); - // For historical reasons, getPendingFacilities() accepts a different sort parameter - // then is used in table filters. We must change the table params sortDirection/sortField - // to a sort string: - const sortDirection = filters.sortDirection?.toLowerCase() ?? "asc"; - const sort = filters?.sortField - ? [`${filters?.sortField}|${sortDirection}`] - : undefined; - const req = { ...filters, sort }; - delete req.sortField; - delete req.sortDirection; + const req = facilitiesFiltersToApi(filters); return useSuspenseQuery({ queryKey: facilityApiQueryKey(["getPendingFacilities", { req }]), @@ -38,3 +30,30 @@ export function useGetPendingFacilities(filters: PendingFacilitiesFilters) { facilityApi.getPendingFacilitiesRaw(req).then(unwrapRawResponse), }); } + +function facilitiesFiltersToApi( + filters: PendingFacilitiesFilters, +): GetPendingFacilitiesRequest { + const { + sortField, + sortDirection: filterSortDirection, + isBefore, + isAfter, + ...rest + } = filters; + + // For historical reasons, getPendingFacilities() accepts a different sort parameter + // then is used in table filters. We must change the table params sortDirection/sortField + // to a sort string: + const sortDirection = filterSortDirection?.toLowerCase() ?? "asc"; + const sort = sortField ? [`${sortField}|${sortDirection}`] : undefined; + + return { + ...rest, + sort, + // The API client expects Date objects... + // which it then immediately converts back to strings :) + isBefore: isBefore ? new Date(isBefore) : undefined, + isAfter: isAfter ? new Date(isAfter) : undefined, + }; +} diff --git a/employee-portal/src/lib/businessModules/inspection/api/queries/useFetchTasksForTeamView.ts b/employee-portal/src/lib/businessModules/inspection/api/queries/useFetchTasksForTeamViewOptions.ts similarity index 67% rename from employee-portal/src/lib/businessModules/inspection/api/queries/useFetchTasksForTeamView.ts rename to employee-portal/src/lib/businessModules/inspection/api/queries/useFetchTasksForTeamViewOptions.ts index b839dea537d5385b8c1903a588b09475e1f95986..a1ed1105f969b442c45a6824716962fd7d6ae847 100644 --- a/employee-portal/src/lib/businessModules/inspection/api/queries/useFetchTasksForTeamView.ts +++ b/employee-portal/src/lib/businessModules/inspection/api/queries/useFetchTasksForTeamViewOptions.ts @@ -8,15 +8,17 @@ import { progressEntryApiQueryKey } from "@/lib/businessModules/inspection/api/q import { useGetHeadersForOfflineCaching } from "@/lib/businessModules/inspection/shared/offline/useGetHeadersForOfflineCaching"; import { TeamviewFilters, - useFetchTasksForTeamViewTemplate, + useFetchTasksForTeamViewTemplateOptions, } from "@/lib/shared/api/queries/tasks"; -export function useFetchTasksForTeamView(teamviewFilters: TeamviewFilters) { +export function useFetchTasksForTeamViewOptions( + teamviewFilters: TeamviewFilters, +) { const getPreCacheForOfflineModeHeaders = useGetHeadersForOfflineCaching(); - return useFetchTasksForTeamViewTemplate( + return useFetchTasksForTeamViewTemplateOptions({ useTaskApi, - progressEntryApiQueryKey, + queryKeyFactory: progressEntryApiQueryKey, teamviewFilters, - getPreCacheForOfflineModeHeaders, - ); + getInitOverrides: getPreCacheForOfflineModeHeaders, + }); } diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/ChecklistDefinitionOverviewTable.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/ChecklistDefinitionOverviewTable.tsx deleted file mode 100644 index 1855e9422390d855b9faa41410278f13b2d2e28f..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/ChecklistDefinitionOverviewTable.tsx +++ /dev/null @@ -1,297 +0,0 @@ -/** - * Copyright 2024 SCOOP Software GmbH, cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -"use client"; - -import { ApiUserRole } from "@eshg/employee-portal-api/base"; -import { - ApiChecklistDefinition, - ApiChecklistDefinitionVersion, -} from "@eshg/employee-portal-api/inspection"; -import { - Close, - CloudSync, - CloudUpload, - Edit, - Hexagon, - History, -} from "@mui/icons-material"; -import { Stack } from "@mui/joy"; -import { CellContext, Row, createColumnHelper } from "@tanstack/react-table"; -import { useState } from "react"; -import { isNonNullish, isNullish } from "remeda"; - -import { useGetChecklistDefinitions } from "@/lib/businessModules/inspection/api/queries/checklistDefinition"; -import { ChecklistVersionsSidebar } from "@/lib/businessModules/inspection/components/checklistDefinition/sidebars/ChecklistVersionsSidebar"; -import { UploadChecklistToRepoSidebar } from "@/lib/businessModules/inspection/components/checklistDefinition/sidebars/UploadChecklistToRepoSidebar"; -import { routes } from "@/lib/businessModules/inspection/shared/routes"; -import { ActionsMenu } from "@/lib/shared/components/buttons/ActionsMenu"; -import { DataTable } from "@/lib/shared/components/table/DataTable"; -import { TablePage } from "@/lib/shared/components/table/TablePage"; -import { TableSheet } from "@/lib/shared/components/table/TableSheet"; -import { useHasUserRolesCheck } from "@/lib/shared/hooks/useAccessControl"; - -const columnHelper = createColumnHelper<ApiChecklistDefinition>(); - -type UserActivityState = - | { type: "view-table" } - | { type: "view-history"; checklistDefinitionId: string } - | { - type: "upload-cld-to-repo"; - checklistDefinition?: ApiChecklistDefinition; - create: boolean; - }; - -const initialUserActivity: UserActivityState = { type: "view-table" }; - -export function ChecklistDefinitionOverviewTable() { - const [ - canEditCoreChecklists, - canUploadRepoChecklists, - canUploadRepoCoreChecklists, - canEditChecklists, - ] = useHasUserRolesCheck([ - ApiUserRole.InspectionCorechecklistdefinitionsEdit, - ApiUserRole.InspectionCentralrepositoryWrite, - ApiUserRole.InspectionCentralrepositoryWriteCorechecklists, - ApiUserRole.InspectionChecklistdefinitionsWrite, - ]); - - const { data: checklists, isFetching } = useGetChecklistDefinitions(); - - const [userActivity, setUserActivity] = - useState<UserActivityState>(initialUserActivity); - - function handleHistoryButtonClick(defId: string) { - setUserActivity({ - type: "view-history", - checklistDefinitionId: defId, - }); - } - - function handleUploadRepoButtonClick(def: ApiChecklistDefinition) { - setUserActivity({ - type: "upload-cld-to-repo", - checklistDefinition: def, - create: true, - }); - } - - function handleUpdateRepoButtonClick(def: ApiChecklistDefinition) { - setUserActivity({ - type: "upload-cld-to-repo", - checklistDefinition: def, - create: false, - }); - } - - function handleSidebarClosed() { - setUserActivity(initialUserActivity); - } - - function versionsCellRenderFunction( - props: CellContext<ApiChecklistDefinition, ApiChecklistDefinitionVersion[]>, - ): string { - let repoVersionString = ""; - if (isNonNullish(props.row.original.mostRecentRepositoryVersion)) { - repoVersionString = `R${props.row.original.mostRecentRepositoryVersion.toString()}-`; - } - return ( - repoVersionString + props.row.original.mostRecentVersionNr.toString() - ); - } - - function showUploadRepoMenuEntry(def: ApiChecklistDefinition): boolean { - if (isNonNullish(def.mostRecentRepositoryVersion)) { - return false; - } - if (!def.coreChecklist) { - return canUploadRepoChecklists; - } else { - return canUploadRepoCoreChecklists; - } - } - - function showUpdateRepoMenuEntry(def: ApiChecklistDefinition): boolean { - if ( - isNullish(def.mostRecentRepositoryVersion) || - def.mostRecentVersionBasedOnRepo === def.mostRecentVersionNr - ) { - return false; - } - if (!def.coreChecklist) { - return canUploadRepoChecklists; - } else { - return canUploadRepoCoreChecklists; - } - } - - const columns = [ - columnHelper.accessor("name", { - header: "Name", - cell: (info) => ( - <Stack direction="row" spacing={0.5}> - {info.row.original.coreChecklist && ( - <Hexagon - aria-hidden={false} - titleAccess="Kerncheckliste" - aria-label="Kerncheckliste" - /> - )} - {info.renderValue()} - </Stack> - ), - meta: { - canNavigate: { - parentRow: true, - }, - width: 406, - }, - }), - columnHelper.accessor("versions", { - header: "Version", - cell: versionsCellRenderFunction, - sortingFn: (colA, colB) => { - return ( - (colA.original.mostRecentRepositoryVersion ?? 0) - - (colB.original.mostRecentRepositoryVersion ?? 0) || - colA.original.mostRecentVersionNr - colB.original.mostRecentVersionNr - ); - }, - meta: { - canNavigate: { - parentRow: true, - }, - width: 200, - }, - }), - columnHelper.accessor("objectType.name", { - header: "Objekttyp", - meta: { - canNavigate: { - parentRow: true, - }, - width: 406, - }, - }), - columnHelper.accessor("deleted", { - header: "Gelöscht", - cell: (info) => ( - <> - {info.row.original.deleted && ( - <Close - aria-hidden={false} - titleAccess="Gelöscht" - aria-label="Gelöscht" - /> - )} - </> - ), - meta: { - width: 65, - }, - }), - columnHelper.accessor("mostRecentVersionId", { - header: "Aktionen", - enableSorting: false, - cell: (info) => { - const checklistRow = info.row.original; - const hideEdit = - !canEditChecklists || - (checklistRow.coreChecklist && !canEditCoreChecklists); - return ( - <ActionsMenu - actionItems={[ - ...(hideEdit - ? [] - : [ - { - label: "Anpassen", - onClick: routes.checklists.definitions.newVersion( - checklistRow.id, - checklistRow.mostRecentVersionId, - ), - startDecorator: <Edit />, - }, - ]), - { - label: "Historie", - onClick: () => { - handleHistoryButtonClick(checklistRow.id); - }, - startDecorator: <History />, - }, - ...(showUploadRepoMenuEntry(checklistRow) - ? [ - { - label: "Bereitstellen", - onClick: () => { - handleUploadRepoButtonClick(checklistRow); - }, - startDecorator: <CloudUpload />, - }, - ] - : []), - ...(showUpdateRepoMenuEntry(checklistRow) - ? [ - { - label: "Aktualisieren", - onClick: () => { - handleUpdateRepoButtonClick(checklistRow); - }, - startDecorator: <CloudSync />, - }, - ] - : []), - ]} - /> - ); - }, - meta: { - width: 96, - }, - }), - ]; - - return ( - <> - <TablePage fullHeight> - <TableSheet loading={isFetching}> - <DataTable - data={checklists} - columns={columns} - rowNavRoute={getRowRoute} - focusColumnHeader={"Name"} - striped - /> - </TableSheet> - </TablePage> - - {userActivity.type === "view-history" && ( - <ChecklistVersionsSidebar - open - onClose={handleSidebarClosed} - checklistDefinitionId={userActivity.checklistDefinitionId} - /> - )} - - {userActivity.type === "upload-cld-to-repo" && ( - <UploadChecklistToRepoSidebar - open - onClose={handleSidebarClosed} - checklistDefinition={userActivity.checklistDefinition} - create={userActivity.create} - /> - )} - </> - ); -} - -function getRowRoute(row: Row<ApiChecklistDefinition>) { - return routes.checklists.definitions.viewVersion( - row.original.id, - row.original.mostRecentVersionId, - ); -} diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/EditChecklistDefinition.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/EditChecklistDefinition.tsx index 82f51449de8a498f2ecce4bb273c8745961ac67b..d065af99b16fda0de8372866d246d8d8a2f2c50c 100644 --- a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/EditChecklistDefinition.tsx +++ b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/EditChecklistDefinition.tsx @@ -15,8 +15,9 @@ import { isDefined } from "remeda"; import { FormChecklistDefinitionVersion, + useAddChecklistDefinitionVersion, useCreateChecklistDefinition, - useUpdateChecklistDefinition, + useEditDraftChecklistDefinitionVersion, } from "@/lib/businessModules/inspection/api/mutations/checklistDefinition"; import { ChecklistDefinitionHeaderCard } from "@/lib/businessModules/inspection/components/checklistDefinition/header/ChecklistDefinitionHeaderCard"; import { ChecklistDefinitionHeaderRow } from "@/lib/businessModules/inspection/components/checklistDefinition/header/ChecklistDefinitionHeaderRow"; @@ -38,9 +39,15 @@ export function EditChecklistDefinition({ const router = useRouter(); const { mutateAsync: createChecklist } = useCreateChecklistDefinition(); - const { mutateAsync: updateChecklist } = useUpdateChecklistDefinition(); + const { mutateAsync: addCldVersion } = useAddChecklistDefinitionVersion(); + const { mutateAsync: editDraftCldVersion } = + useEditDraftChecklistDefinitionVersion(); - const isNewestVersion = cldVersion?.context.validTo === undefined; + const hasDraft = cldVersion?.hasDraft ?? false; + const isNewestVersion = + cldVersion === undefined || + (cldVersion?.context.validTo === undefined && + cldVersion?.context.published === true); const readOnlyMode = readonly ?? !isNewestVersion; const formData: FormChecklistDefinitionVersion = useMemo( @@ -57,6 +64,7 @@ export function EditChecklistDefinition({ sections: [], expandable: true, deleted: false, + published: true, }, isCoreChecklist: false, objectTypeId: "", @@ -64,16 +72,39 @@ export function EditChecklistDefinition({ [cldVersion], ); + let publish = true; async function sendToBackend(values: FormChecklistDefinitionVersion) { if (cldVersion) { - await updateChecklist( - { defId: cldVersion.context.defId, cldVersion: values }, - { onSuccess: () => router.push(routes.checklists.definitions.index) }, - ); + if (!hasDraft) { + await addCldVersion( + { + defId: cldVersion.context.defId, + cldVersion: { + ...values, + context: { ...values.context, published: publish }, + }, + }, + { onSuccess: () => router.push(routes.checklists.definitions.index) }, + ); + } else { + await editDraftCldVersion( + { + versionId: cldVersion.context.id, + cldVersion: { + ...values, + context: { ...values.context, published: publish }, + }, + }, + { onSuccess: () => router.push(routes.checklists.definitions.index) }, + ); + } } else { - await createChecklist(values, { - onSuccess: () => router.push(routes.checklists.definitions.index), - }); + await createChecklist( + { ...values, context: { ...values.context, published: publish } }, + { + onSuccess: () => router.push(routes.checklists.definitions.index), + }, + ); } } @@ -96,6 +127,8 @@ export function EditChecklistDefinition({ versionId={cldVersion?.context.id} isCoreChecklist={cldVersion?.isCoreChecklist} isSubmitting={isSubmitting} + hasDraft={hasDraft} + onPublish={(shouldPublish) => (publish = shouldPublish)} /> )} <ChecklistDefinitionHeaderCard diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/header/ChecklistDefinitionHeaderCard.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/header/ChecklistDefinitionHeaderCard.tsx index cbedd829293f32a3a89723c5e56513bc39819dbb..0330d3952caccbcbd07354c3304fb5145744497c 100644 --- a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/header/ChecklistDefinitionHeaderCard.tsx +++ b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/header/ChecklistDefinitionHeaderCard.tsx @@ -58,7 +58,7 @@ export function ChecklistDefinitionHeaderCard({ <Stack direction="row" gap={4}> <CheckboxField name="context.deleted" - label="Als gelöscht markieren" + label="Als Inaktiv markieren" disabled={ readOnlyMode || (values.isCoreChecklist && !canEditCoreChecklists) } diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/header/ChecklistDefinitionHeaderRow.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/header/ChecklistDefinitionHeaderRow.tsx index 0ed025e438d4dd415ba1148a811aea0518fa825b..f0f7bb112b725788088f41118b1396dcf1276622 100644 --- a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/header/ChecklistDefinitionHeaderRow.tsx +++ b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/header/ChecklistDefinitionHeaderRow.tsx @@ -24,6 +24,8 @@ interface ChecklistDefinitionHeaderRowProps { versionId?: string; isCoreChecklist?: boolean; isSubmitting?: boolean; + hasDraft?: boolean; + onPublish(publish: boolean): void; } export function ChecklistDefinitionHeaderRow({ @@ -35,6 +37,8 @@ export function ChecklistDefinitionHeaderRow({ versionId, isCoreChecklist, isSubmitting = false, + hasDraft, + onPublish, }: Readonly<ChecklistDefinitionHeaderRowProps>) { const [canEditChecklists, canEditCoreChecklists] = useHasUserRolesCheck([ ApiUserRole.InspectionChecklistdefinitionsWrite, @@ -42,9 +46,10 @@ export function ChecklistDefinitionHeaderRow({ ]); const canSeeSaveActions = canEditChecklists && (canEditCoreChecklists || !isCoreChecklist); - const canCreateNewVersion = newestVersion && !!defId && !!versionId; + const canCreateNewVersion = + newestVersion && !!defId && !!versionId && !hasDraft; - const versionLabel = (version ?? 0) + (readOnlyMode ? 0 : 1); + const versionLabel = (version ?? 0) + (readOnlyMode || hasDraft ? 0 : 1); const newVersionUrl = routes.checklists.definitions.newVersion( defId!, @@ -77,7 +82,28 @@ export function ChecklistDefinitionHeaderRow({ Neue Version anlegen </InternalLinkButton> ) : ( - <SubmitButton submitting={isSubmitting}>Speichern</SubmitButton> + <Stack + spacing={2} + direction="row" + alignItems="center" + justifyContent={"space-between"} + > + <SubmitButton + key="draft" + variant="outlined" + submitting={isSubmitting} + onClick={() => onPublish(false)} + > + Als Entwurf speichern + </SubmitButton> + <SubmitButton + key="publish" + submitting={isSubmitting} + onClick={() => onPublish(true)} + > + Checkliste veröffentlichen + </SubmitButton> + </Stack> ))} </Stack> ); diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/helpers/helpers.ts b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/helpers/helpers.ts index 0967a3762fd08fb31936e968638038f65ccf122e..0769d172df6eb6c69db48b8ecb8f6ad34553869c 100644 --- a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/helpers/helpers.ts +++ b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/helpers/helpers.ts @@ -15,6 +15,8 @@ import { } from "@eshg/employee-portal-api/inspection"; import { v4 as uuidv4 } from "uuid"; +import { ConfirmationDialogProps } from "@/lib/shared/components/confirmationDialog/ConfirmationDialog"; + function getId( partial: Partial<ApiCLSectionContextElementsInner>, keepId: boolean, @@ -153,3 +155,21 @@ export function createChecklistElement( return creator(partial, keepId); } + +export function showPublishChecklistDefinitionDialog( + openConfirmationDialog: ( + confirmationDialog: Omit<ConfirmationDialogProps, "open" | "onClose"> & { + onClose?: ConfirmationDialogProps["onClose"]; + }, + ) => void, + cldName: string, + onConfirm: () => Promise<void> | void, +) { + openConfirmationDialog({ + title: "Checklisten-Definition veröffentlichen?", + description: `Möchten Sie den Entwurf “${cldName}†wirklich veröffentlichen? Danach sind keine Änderungen mehr möglich. Sie können jedoch weiterhin neue Versionen basierend auf diesem Entwurf erstellen.`, + confirmLabel: "Veröffentlichen", + cancelLabel: "Abbrechen", + onConfirm: onConfirm, + }); +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/overview/ChecklistDefinitionOverviewTable.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/overview/ChecklistDefinitionOverviewTable.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2324da84cea7852ea3c80994655524d22b922968 --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/overview/ChecklistDefinitionOverviewTable.tsx @@ -0,0 +1,172 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiUserRole } from "@eshg/employee-portal-api/base"; +import { ApiChecklistDefinition } from "@eshg/employee-portal-api/inspection"; +import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; +import { Row } from "@tanstack/react-table"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; + +import { + useAddChecklistDefinitionVersion, + useEditDraftChecklistDefinitionVersion, +} from "@/lib/businessModules/inspection/api/mutations/checklistDefinition"; +import { useGetChecklistDefinitions } from "@/lib/businessModules/inspection/api/queries/checklistDefinition"; +import { generateChecklistDefinitionOverviewTableColumns } from "@/lib/businessModules/inspection/components/checklistDefinition/overview/columns"; +import { UploadChecklistToRepoSidebar } from "@/lib/businessModules/inspection/components/checklistDefinition/sidebars/UploadChecklistToRepoSidebar"; +import { ChecklistVersionsSidebar } from "@/lib/businessModules/inspection/components/checklistDefinition/sidebars/history/ChecklistVersionsSidebar"; +import { routes } from "@/lib/businessModules/inspection/shared/routes"; +import { useConfirmationDialog } from "@/lib/shared/components/confirmationDialog/ConfirmationDialogProvider"; +import { DataTable } from "@/lib/shared/components/table/DataTable"; +import { TablePage } from "@/lib/shared/components/table/TablePage"; +import { TableSheet } from "@/lib/shared/components/table/TableSheet"; +import { useHasUserRolesCheck } from "@/lib/shared/hooks/useAccessControl"; + +type UserActivityState = + | { type: "view-table" } + | { + type: "view-history"; + checklistDefinition: ApiChecklistDefinition; + } + | { + type: "upload-cld-to-repo"; + checklistDefinition?: ApiChecklistDefinition; + create: boolean; + }; + +const initialUserActivity: UserActivityState = { type: "view-table" }; + +export function ChecklistDefinitionOverviewTable() { + const { openConfirmationDialog } = useConfirmationDialog(); + const snackbar = useSnackbar(); + const [ + canEditCoreChecklists, + canUploadRepoChecklists, + canUploadRepoCoreChecklists, + canEditChecklists, + ] = useHasUserRolesCheck([ + ApiUserRole.InspectionCorechecklistdefinitionsEdit, + ApiUserRole.InspectionCentralrepositoryWrite, + ApiUserRole.InspectionCentralrepositoryWriteCorechecklists, + ApiUserRole.InspectionChecklistdefinitionsWrite, + ]); + + const { data: checklists, isFetching } = useGetChecklistDefinitions(); + const { mutateAsync: addCldVersion } = useAddChecklistDefinitionVersion(); + const { mutateAsync: editDraftCldVersion } = + useEditDraftChecklistDefinitionVersion(); + const router = useRouter(); + + const [userActivity, setUserActivity] = + useState<UserActivityState>(initialUserActivity); + + function handleHistoryButtonClick(def: ApiChecklistDefinition) { + setUserActivity({ + type: "view-history", + checklistDefinition: def, + }); + } + + function handleUploadRepoButtonClick(def: ApiChecklistDefinition) { + setUserActivity({ + type: "upload-cld-to-repo", + checklistDefinition: def, + create: true, + }); + } + + function handleUpdateRepoButtonClick(def: ApiChecklistDefinition) { + setUserActivity({ + type: "upload-cld-to-repo", + checklistDefinition: def, + create: false, + }); + } + + function handleSidebarClosed() { + setUserActivity(initialUserActivity); + } + + const columns = generateChecklistDefinitionOverviewTableColumns( + snackbar, + router, + { + canEditCoreChecklists, + canUploadRepoChecklists, + canUploadRepoCoreChecklists, + canEditChecklists, + }, + { + openConfirmationDialog, + handleHistoryButtonClick, + handleUploadRepoButtonClick, + handleUpdateRepoButtonClick, + addCldVersion, + editDraftCldVersion, + }, + ); + + function onRowClick(row: Row<ApiChecklistDefinition>): string { + const def = row.original; + if (!def.mostRecentVersion.context.published) { + return (def.coreChecklist && canEditCoreChecklists) || + (!def.coreChecklist && canEditChecklists) + ? routes.checklists.definitions.newVersion( + row.original.id, + row.original.mostRecentVersion.context.id, + ) + : routes.checklists.definitions.viewVersion( + row.original.id, + row.original.mostRecentVersion.context.id, + ); + } + return routes.checklists.definitions.viewVersion( + row.original.id, + row.original.mostRecentVersion.context.id, + ); + } + + return ( + <> + <TablePage fullHeight> + <TableSheet loading={isFetching}> + <DataTable + data={checklists} + columns={columns} + rowNavRoute={onRowClick} + focusColumnHeader={"Name"} + striped + /> + </TableSheet> + </TablePage> + + {userActivity.type === "view-history" && ( + <ChecklistVersionsSidebar + open + onClose={handleSidebarClosed} + checklistDefinition={userActivity.checklistDefinition} + onUploadCldClick={() => + handleUploadRepoButtonClick(userActivity.checklistDefinition) + } + onUpdateCldClick={() => + handleUpdateRepoButtonClick(userActivity.checklistDefinition) + } + /> + )} + + {userActivity.type === "upload-cld-to-repo" && ( + <UploadChecklistToRepoSidebar + open + onClose={handleSidebarClosed} + checklistDefinition={userActivity.checklistDefinition} + create={userActivity.create} + /> + )} + </> + ); +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/overview/columns.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/overview/columns.tsx new file mode 100644 index 0000000000000000000000000000000000000000..6fb1ed283a98ccaf4b561ad1a5f535098fb8ab3a --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/overview/columns.tsx @@ -0,0 +1,527 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + ApiChecklistDefinition, + ApiChecklistDefinitionVersion, +} from "@eshg/employee-portal-api/inspection"; +import { Snackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; +import { formatDateTime } from "@eshg/lib-portal/formatters/dateTime"; +import { + CheckCircle, + CloudSync, + CloudUpload, + CopyAll, + CropFree, + Edit, + History, +} from "@mui/icons-material"; +import { Chip, Stack, Typography } from "@mui/joy"; +import { UseMutateAsyncFunction } from "@tanstack/react-query"; +import { CellContext, createColumnHelper } from "@tanstack/react-table"; +import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"; +import { isNonNullish, isNullish } from "remeda"; + +import { FormChecklistDefinitionVersion } from "@/lib/businessModules/inspection/api/mutations/checklistDefinition"; +import { showPublishChecklistDefinitionDialog } from "@/lib/businessModules/inspection/components/checklistDefinition/helpers/helpers"; +import { ActiveChecklistIcon } from "@/lib/businessModules/inspection/components/icons/ActiveChecklistIcon"; +import { CorechecklistIcon } from "@/lib/businessModules/inspection/components/icons/CorechecklistIcon"; +import { ExclusiveCorechecklistIcon } from "@/lib/businessModules/inspection/components/icons/ExclusiveCorechecklistIcon"; +import { InactiveChecklistIcon } from "@/lib/businessModules/inspection/components/icons/InactiveChecklistIcon"; +import { routes } from "@/lib/businessModules/inspection/shared/routes"; +import { + ActionsItem, + ActionsMenu, +} from "@/lib/shared/components/buttons/ActionsMenu"; +import { ConfirmationDialogProps } from "@/lib/shared/components/confirmationDialog/ConfirmationDialog"; + +const columnHelper = createColumnHelper<ApiChecklistDefinition>(); + +interface ChecklistDefinitionOverviewPermissions { + canEditCoreChecklists: boolean; + canUploadRepoChecklists: boolean; + canUploadRepoCoreChecklists: boolean; + canEditChecklists: boolean; +} + +export function generateChecklistDefinitionOverviewTableColumns( + snackbar: Snackbar, + router: AppRouterInstance, + { + canEditCoreChecklists, + canUploadRepoChecklists, + canUploadRepoCoreChecklists, + canEditChecklists, + }: ChecklistDefinitionOverviewPermissions, + { + addCldVersion, + openConfirmationDialog, + handleHistoryButtonClick, + handleUploadRepoButtonClick, + handleUpdateRepoButtonClick, + editDraftCldVersion, + }: ActionItemActions, +) { + return [ + columnHelper.display({ + header: "", + id: "coreChecklist", + cell: (info) => ( + <Stack direction="row"> + {info.row.original.coreChecklist && ( + <> + {info.row.original.expandable ? ( + <CorechecklistIcon + aria-hidden={false} + titleAccess="Kern-Checkliste" + aria-label="Kern-Checkliste" + /> + ) : ( + <ExclusiveCorechecklistIcon + aria-hidden={false} + titleAccess="Exklusive Kern-Checkliste" + aria-label="Exklusive Kern-Checkliste" + /> + )} + </> + )} + </Stack> + ), + meta: { + width: 40, + }, + }), + columnHelper.display({ + header: "", + id: "deleted", + cell: (info) => ( + <Stack direction="row"> + {info.row.original.mostRecentVersion.context.deleted && ( + <InactiveChecklistIcon + aria-hidden={false} + titleAccess="inaktive Checkliste" + aria-label="inaktive Checkliste" + /> + )} + </Stack> + ), + meta: { + width: 40, + }, + }), + columnHelper.accessor("mostRecentVersion.context.name", { + header: "Name", + cell: (info) => ( + <Stack direction="row" spacing={0.5}> + {info.renderValue()} + </Stack> + ), + meta: { + canNavigate: { + parentRow: true, + }, + width: 406, + }, + }), + columnHelper.accessor("objectType.name", { + header: "Objekttyp", + meta: { + width: 366, + }, + }), + columnHelper.accessor("versions", { + header: "Versionen", + cell: versionsCellRenderFunction, + sortingFn: (colA, colB) => { + return ( + (colA.original.mostRecentRepositoryVersion ?? 0) - + (colB.original.mostRecentRepositoryVersion ?? 0) || + colA.original.mostRecentVersion.context.version - + colB.original.mostRecentVersion.context.version + ); + }, + meta: { + canNavigate: { + parentRow: true, + }, + width: 200, + }, + }), + columnHelper.display({ + header: "Status", + cell: (info) => ( + <Stack + direction="row" + gap={1} + flexWrap={undefined} + sx={{ + overflow: "visible", + }} + > + {!info.row.original.published && ( + <Chip variant="soft" color="warning" size="md" sx={{ margin: 0 }}> + Entwurf + </Chip> + )} + {(info.row.original.published || + info.row.original.mostRecentVersion.context.version > 1) && ( + <Chip variant="soft" color="success" size="md" sx={{ margin: 0 }}> + Veröffentlicht + </Chip> + )} + </Stack> + ), + meta: { + canNavigate: { + parentRow: true, + }, + width: 200, + }, + }), + columnHelper.accessor("lastModified", { + header: "Zuletzt aktualisiert", + cell: (info) => ( + <Typography>{formatDateTime(info.getValue())}</Typography> + ), + meta: { + width: 186, + }, + }), + columnHelper.display({ + header: "Aktionen", + enableSorting: false, + cell: (info) => { + const checklistRow = info.row.original; + return ( + <ActionsMenu + actionItems={generateActionItems( + checklistRow, + snackbar, + router, + { + showUploadRepoMenuEntry: showUploadRepoMenuEntry(checklistRow, { + canUploadRepoChecklists, + canUploadRepoCoreChecklists, + }), + showUpdateRepoMenuEntry: showUpdateRepoMenuEntry(checklistRow, { + canUploadRepoChecklists, + canUploadRepoCoreChecklists, + }), + canEditChecklists, + canEditCoreChecklists, + }, + { + addCldVersion, + openConfirmationDialog, + handleHistoryButtonClick, + handleUploadRepoButtonClick, + handleUpdateRepoButtonClick, + editDraftCldVersion, + }, + )} + /> + ); + }, + meta: { + width: 138, + }, + }), + ]; +} + +function versionsCellRenderFunction( + props: CellContext<ApiChecklistDefinition, ApiChecklistDefinitionVersion[]>, +): string { + let versionString = `lokal ${props.row.original.mostRecentVersion.context.version.toString()}`; + if (isNonNullish(props.row.original.mostRecentRepositoryVersion)) { + versionString = + versionString + + ` remote ${props.row.original.mostRecentRepositoryVersion.toString()}`; + } + return versionString; +} + +interface ActionItemPermissions { + showUploadRepoMenuEntry: boolean; + showUpdateRepoMenuEntry: boolean; + canEditChecklists: boolean; + canEditCoreChecklists: boolean; +} + +interface ActionItemActions { + openConfirmationDialog: ( + confirmationDialog: Omit<ConfirmationDialogProps, "open" | "onClose"> & { + onClose?: ConfirmationDialogProps["onClose"]; + }, + ) => void; + handleHistoryButtonClick: (def: ApiChecklistDefinition) => void; + handleUploadRepoButtonClick: (def: ApiChecklistDefinition) => void; + handleUpdateRepoButtonClick: (def: ApiChecklistDefinition) => void; + addCldVersion: UseMutateAsyncFunction< + ApiChecklistDefinitionVersion, + Error, + { + defId: string; + cldVersion: + | FormChecklistDefinitionVersion + | ApiChecklistDefinitionVersion; + }, + unknown + >; + editDraftCldVersion: UseMutateAsyncFunction< + ApiChecklistDefinitionVersion, + Error, + { + versionId: string; + cldVersion: + | FormChecklistDefinitionVersion + | ApiChecklistDefinitionVersion; + }, + unknown + >; +} + +function generateActionItems( + definition: ApiChecklistDefinition, + snackbar: Snackbar, + router: AppRouterInstance, + { + showUploadRepoMenuEntry, + showUpdateRepoMenuEntry, + canEditChecklists, + canEditCoreChecklists, + }: ActionItemPermissions, + { + openConfirmationDialog, + handleHistoryButtonClick, + handleUploadRepoButtonClick, + handleUpdateRepoButtonClick, + addCldVersion, + editDraftCldVersion, + }: ActionItemActions, +) { + const hideEdit = + !canEditChecklists || (definition.coreChecklist && !canEditCoreChecklists); + const published = definition.published; + const deleted = definition.deleted; + const actionItems: ActionsItem[] = []; + const mostRecentVersion = definition.mostRecentVersion; + + if (!published) { + actionItems.push( + hideEdit + ? { + label: "Anzeigen", + onClick: routes.checklists.definitions.viewVersion( + definition.id, + definition.mostRecentVersion.context.id, + ), + startDecorator: <CropFree />, + } + : { + label: "Bearbeiten", + onClick: routes.checklists.definitions.newVersion( + definition.id, + definition.mostRecentVersion.context.id, + ), + startDecorator: <Edit />, + }, + { + label: "Historie", + onClick: () => handleHistoryButtonClick(definition), + startDecorator: <History />, + }, + ...(hideEdit + ? [] + : [ + { + label: "Veröffentlichen", + onClick: () => + showPublishChecklistDefinitionDialog( + openConfirmationDialog, + mostRecentVersion.context.name, + async () => { + await editDraftCldVersion( + { + versionId: mostRecentVersion.context.id, + cldVersion: { + ...mostRecentVersion, + context: { + ...mostRecentVersion.context, + published: true, + }, + }, + }, + { + onSuccess: () => { + snackbar.confirmation( + "Die Checkliste wurde veröffentlicht und kann nun eingesetzt werden.", + ); + router.push(routes.checklists.definitions.index); + }, + }, + ); + }, + ), + startDecorator: <CheckCircle />, + }, + ]), + ); + } else { + actionItems.push( + ...(hideEdit + ? [ + { + label: "Anzeigen", + onClick: routes.checklists.definitions.viewVersion( + definition.id, + definition.mostRecentVersion.context.id, + ), + startDecorator: <CropFree />, + }, + ] + : [ + { + label: "Für neue Version nutzen", + onClick: routes.checklists.definitions.newVersion( + definition.id, + definition.mostRecentVersion.context.id, + ), + startDecorator: <CopyAll />, + }, + ]), + { + label: "Historie", + onClick: () => handleHistoryButtonClick(definition), + startDecorator: <History />, + }, + ...(showUploadRepoMenuEntry + ? [ + { + label: "Hochladen", + onClick: () => { + handleUploadRepoButtonClick(definition); + }, + startDecorator: <CloudUpload />, + }, + ] + : []), + ...(showUpdateRepoMenuEntry + ? [ + { + label: "Aktualisieren", + onClick: () => { + handleUpdateRepoButtonClick(definition); + }, + startDecorator: <CloudSync />, + }, + ] + : []), + ...(hideEdit + ? [] + : [ + deleted + ? { + label: "Aktiv stellen", + onClick: async () => { + await addCldVersion( + { + defId: mostRecentVersion.context.defId, + cldVersion: { + ...mostRecentVersion, + context: { + ...mostRecentVersion.context, + published: true, + deleted: false, + }, + }, + }, + { + onSuccess: () => + router.push(routes.checklists.definitions.index), + }, + ); + }, + startDecorator: <ActiveChecklistIcon />, + } + : { + label: "Inaktiv stellen", + onClick: async () => { + await addCldVersion( + { + defId: mostRecentVersion.context.defId, + cldVersion: { + ...mostRecentVersion, + context: { + ...mostRecentVersion.context, + published: true, + deleted: true, + }, + }, + }, + { + onSuccess: () => + router.push(routes.checklists.definitions.index), + }, + ); + }, + startDecorator: <InactiveChecklistIcon />, + }, + ]), + ); + } + + return actionItems; +} + +export function showUploadRepoMenuEntry( + def: ApiChecklistDefinition, + { + canUploadRepoChecklists, + canUploadRepoCoreChecklists, + }: { + canUploadRepoChecklists: boolean; + canUploadRepoCoreChecklists: boolean; + }, +): boolean { + if ( + isNonNullish(def.mostRecentRepositoryVersion) || + !def.published || + def.deleted + ) { + return false; + } + if (!def.coreChecklist) { + return canUploadRepoChecklists; + } else { + return canUploadRepoCoreChecklists; + } +} + +export function showUpdateRepoMenuEntry( + def: ApiChecklistDefinition, + { + canUploadRepoChecklists, + canUploadRepoCoreChecklists, + }: { + canUploadRepoChecklists: boolean; + canUploadRepoCoreChecklists: boolean; + }, +): boolean { + if ( + isNullish(def.mostRecentRepositoryVersion) || + def.mostRecentVersionBasedOnRepo === + def.mostRecentVersion.context.version || + !def.published || + def.deleted + ) { + return false; + } + if (!def.coreChecklist) { + return canUploadRepoChecklists; + } else { + return canUploadRepoCoreChecklists; + } +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/ChecklistVersionsSidebar.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/ChecklistVersionsSidebar.tsx deleted file mode 100644 index d1424366626d6ff090f683a16e0cba2cd4bcd4e7..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/ChecklistVersionsSidebar.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Copyright 2024 SCOOP Software GmbH, cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -"use client"; - -import { ApiUserRole } from "@eshg/employee-portal-api/base"; -import { InternalLinkButton } from "@eshg/lib-portal/components/navigation/InternalLinkButton"; -import { Hexagon } from "@mui/icons-material"; -import AddIcon from "@mui/icons-material/Add"; -import { Box, Stack, Typography } from "@mui/joy"; - -import { useGetChecklistDefinitionVersions } from "@/lib/businessModules/inspection/api/queries/checklistDefinition"; -import { routes } from "@/lib/businessModules/inspection/shared/routes"; -import { OverlayBoundary } from "@/lib/shared/components/boundaries/OverlayBoundary"; -import { Sidebar } from "@/lib/shared/components/sidebar/Sidebar"; -import { SidebarContent } from "@/lib/shared/components/sidebar/SidebarContent"; -import { useHasUserRolesCheck } from "@/lib/shared/hooks/useAccessControl"; - -import { ChecklistVersionsTable } from "./ChecklistVersionsTable"; - -interface CreateChecklistVersionsSidebarProps { - open: boolean; - onClose: () => void; - checklistDefinitionId: string; -} - -export function ChecklistVersionsSidebar( - props: CreateChecklistVersionsSidebarProps, -) { - return ( - <OverlayBoundary> - <ChecklistVersionsSidebarWithQuery {...props} /> - </OverlayBoundary> - ); -} - -function ChecklistVersionsSidebarWithQuery({ - open, - onClose, - checklistDefinitionId, -}: Readonly<CreateChecklistVersionsSidebarProps>) { - const { data: versions } = useGetChecklistDefinitionVersions( - checklistDefinitionId, - ); - - const [canEditChecklists, canEditCoreChecklists] = useHasUserRolesCheck([ - ApiUserRole.InspectionChecklistdefinitionsWrite, - ApiUserRole.InspectionCorechecklistdefinitionsEdit, - ]); - const newestVersion = versions.find((v) => v.context.validTo === undefined); - const canAddVersion = - canEditChecklists && - (canEditCoreChecklists || !newestVersion?.isCoreChecklist); - - function handleClose() { - onClose(); - } - - return ( - <Sidebar open={open} onClose={handleClose}> - <SidebarContent title={"Versionen"}> - <Typography - level="h4" - component="p" - textColor={"text.secondary"} - sx={{ mb: 2 }} - > - <Stack direction="row" spacing={0.5}> - {newestVersion?.isCoreChecklist && <Hexagon />} - {newestVersion?.isCoreChecklist - ? "Kerncheckliste" - : "Checkliste"}: {newestVersion?.context.name ?? ""} - </Stack> - </Typography> - {canAddVersion && ( - <Box display="flex" justifyContent="flex-end" sx={{ mb: 2 }}> - <InternalLinkButton - href={routes.checklists.definitions.newVersion( - newestVersion?.context.defId ?? "", - newestVersion?.context.id ?? "", - )} - variant="plain" - startDecorator={<AddIcon />} - > - Neue Version anlegen - </InternalLinkButton> - </Box> - )} - <ChecklistVersionsTable versions={versions} /> - </SidebarContent> - </Sidebar> - ); -} diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/ChecklistVersionsTable.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/ChecklistVersionsTable.tsx deleted file mode 100644 index dfda707a8c0a60b1ef210b6d8288791fb4c6fbf7..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/ChecklistVersionsTable.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Copyright 2024 SCOOP Software GmbH, cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -"use client"; - -import { ApiChecklistDefinitionVersion } from "@eshg/employee-portal-api/inspection"; -import { InternalLink } from "@eshg/lib-portal/components/navigation/InternalLink"; -import { formatDateTime } from "@eshg/lib-portal/formatters/dateTime"; -import { Lock } from "@mui/icons-material"; -import { Stack } from "@mui/joy"; -import { - CellContext, - ColumnHelper, - SortingState, - createColumnHelper, -} from "@tanstack/react-table"; -import { ReactNode } from "react"; -import { isNonNullish } from "remeda"; - -import { isUnknownUser } from "@/lib/businessModules/inspection/shared/isUnknownUser"; -import { routes } from "@/lib/businessModules/inspection/shared/routes"; -import { DataTable } from "@/lib/shared/components/table/DataTable"; -import { UserLink } from "@/lib/shared/components/users/UserLink"; - -const columnHelper: ColumnHelper<ApiChecklistDefinitionVersion> = - createColumnHelper<ApiChecklistDefinitionVersion>(); - -export function ChecklistVersionsTable({ - versions, -}: Readonly<{ - versions: ApiChecklistDefinitionVersion[]; -}>) { - function versionCellRenderFunction( - props: CellContext<ApiChecklistDefinitionVersion, number>, - ): ReactNode { - let repoVersionString = ""; - if (isNonNullish(props.row.original.context.repositoryVersion)) { - repoVersionString = `R${props.row.original.context.repositoryVersion.toString()}-`; - } - return ( - <Stack direction="row" spacing={0.5}> - {!props.row.original.context.expandable && <Lock />} - {repoVersionString + props.row.original.context.version.toString()} - </Stack> - ); - } - - const columns = [ - columnHelper.accessor("context.name", { - header: "Name", - cell: (info) => ( - <InternalLink - href={routes.checklists.definitions.viewVersion( - info.row.original.context.defId, - info.row.original.context.id, - )} - > - {info.renderValue()} - </InternalLink> - ), - }), - columnHelper.accessor("context.version", { - header: "Version", - cell: versionCellRenderFunction, - }), - columnHelper.accessor("modifiedBy", { - header: "Zuletzt bearbeitet", - cell: (props) => { - const modifiedBy = props.getValue(); - - if (!modifiedBy || isUnknownUser(modifiedBy)) { - return; - } - - return <UserLink user={modifiedBy} />; - }, - }), - columnHelper.accessor("context.validFrom", { - header: "Zuletzt bearbeitet", - cell: (props) => formatDateTime(props.getValue()), - }), - ]; - - const initialSorting: SortingState = [ - { - id: "context_version", - desc: true, - }, - ]; - return ( - <DataTable - data={versions} - columns={columns} - sorting={{ - manualSorting: false, - initialSorting, - }} - /> - ); -} diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/UploadChecklistToRepoSidebar.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/UploadChecklistToRepoSidebar.tsx index a317ea1ea4e4f1ebeb46206af08bf7b4f1ddcf94..8cc445e665c396a8fbee45240e62ca8c46e1fae5 100644 --- a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/UploadChecklistToRepoSidebar.tsx +++ b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/UploadChecklistToRepoSidebar.tsx @@ -78,13 +78,13 @@ function UploadChecklistToRepoSidebarWithMutations({ if (create) { await addChecklistDefinitionToCentralRepo({ cldId: checklistDefinition.id, - cldVersion: checklistDefinition.mostRecentVersionNr, + cldVersion: checklistDefinition.mostRecentVersion.context.version, apiChecklistDefinitionCentralRepoRequest: formValues, }); } else { await updateChecklistDefinitionToCentralRepo({ cldId: checklistDefinition.id, - cldVersion: checklistDefinition.mostRecentVersionNr, + cldVersion: checklistDefinition.mostRecentVersion.context.version, apiChecklistDefinitionCentralRepoUpdateRequest: formValues, }); } diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/history/ChecklistVersionsSidebar.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/history/ChecklistVersionsSidebar.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c2ab4f841e79505ffd75ea623bcb602a9617f15e --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/history/ChecklistVersionsSidebar.tsx @@ -0,0 +1,167 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiUserRole } from "@eshg/employee-portal-api/base"; +import { + ApiChecklistDefinition, + ApiChecklistDefinitionVersion, +} from "@eshg/employee-portal-api/inspection"; +import { Alert } from "@eshg/lib-portal/components/Alert"; +import { Stack, Typography } from "@mui/joy"; + +import { useGetChecklistDefinitionVersions } from "@/lib/businessModules/inspection/api/queries/checklistDefinition"; +import { OverlayBoundary } from "@/lib/shared/components/boundaries/OverlayBoundary"; +import { Sidebar } from "@/lib/shared/components/sidebar/Sidebar"; +import { SidebarContent } from "@/lib/shared/components/sidebar/SidebarContent"; +import { useHasUserRolesCheck } from "@/lib/shared/hooks/useAccessControl"; + +import { VersionSheet } from "./VersionSheet"; + +interface CreateChecklistVersionsSidebarProps { + open: boolean; + onClose: () => void; + checklistDefinition: ApiChecklistDefinition; + onUploadCldClick: () => void; + onUpdateCldClick: () => void; +} + +export function ChecklistVersionsSidebar( + props: Readonly<CreateChecklistVersionsSidebarProps>, +) { + return ( + <OverlayBoundary> + <ChecklistVersionsSidebarWithQuery {...props} /> + </OverlayBoundary> + ); +} + +function ChecklistVersionsSidebarWithQuery({ + open, + onClose, + checklistDefinition, + onUploadCldClick, + onUpdateCldClick, +}: Readonly<CreateChecklistVersionsSidebarProps>) { + const { data: versions } = useGetChecklistDefinitionVersions( + checklistDefinition.id, + ); + const nameChangeMap = computeNameChangeMap(versions); + const [canEditChecklists, canEditCoreChecklists] = useHasUserRolesCheck([ + ApiUserRole.InspectionChecklistdefinitionsWrite, + ApiUserRole.InspectionCorechecklistdefinitionsEdit, + ]); + const permissions = { canEditCoreChecklists, canEditChecklists }; + + const newestVersion = versions[versions.length - 1]!; + const oldVersions = versions.slice(0, -1); + + function handleClose() { + onClose(); + } + + return ( + <Sidebar open={open} onClose={handleClose}> + <SidebarContent title={"Historie"}> + <Stack direction="column" gap={4}> + <Typography level="h4" component="p" textColor="text.primary"> + {`Versionen der ${newestVersion.isCoreChecklist ? "Kernchecklisten-Definition" : "Checklisten-Definition"}: “${newestVersion?.context.name ?? ""}“`} + </Typography> + <ChecklistHint version={newestVersion} permissions={permissions} /> + <Stack direction="column" gap={2}> + <Typography fontSize="14px" lineHeight="21px" fontWeight="500"> + {newestVersion.context.published ? "Aktuelle Version" : "Entwurf"} + </Typography> + <VersionSheet + key={newestVersion.context.id} + definition={checklistDefinition} + version={newestVersion} + isCurrentVersion={true} + nameChange={nameChangeMap.get(newestVersion.context.id)} + onUploadCldClick={onUploadCldClick} + onUpdateCldClick={onUpdateCldClick} + /> + {oldVersions.length > 0 && ( + <Typography fontSize="14px" lineHeight="21px" fontWeight="500"> + Ältere Versionen + </Typography> + )} + {oldVersions.toReversed().map((version) => { + return ( + <VersionSheet + key={version.context.id} + definition={checklistDefinition} + version={version} + isCurrentVersion={false} + nameChange={nameChangeMap.get(version.context.id)} + onUploadCldClick={onUploadCldClick} + onUpdateCldClick={onUpdateCldClick} + /> + ); + })} + </Stack> + </Stack> + </SidebarContent> + </Sidebar> + ); +} + +function computeNameChangeMap( + versions: ApiChecklistDefinitionVersion[], +): Map<string, string | undefined> { + const nameChangeList: { key: string; name?: string }[] = []; + + // set nameChangeList.name if previous name != current name, else undefined + versions.forEach((version, idx) => { + if (idx === 0) { + nameChangeList.push({ key: version.context.id, name: undefined }); + } else { + const prevValue = versions[idx - 1]?.context.name; + nameChangeList.push({ + key: version.context.id, + name: + prevValue !== version.context.name ? version.context.name : undefined, + }); + } + }); + + return new Map(nameChangeList.map((v) => [v.key, v.name])); +} + +function ChecklistHint({ + version, + permissions: { canEditCoreChecklists, canEditChecklists }, +}: Readonly<{ + version: ApiChecklistDefinitionVersion; + permissions: { canEditCoreChecklists: boolean; canEditChecklists: boolean }; +}>) { + return ( + <> + {version.context.published && + version.context.deleted && + (version.isCoreChecklist ? ( + <Alert + color={"primary"} + message={`Inaktive Checklisten können nicht für Begehungen eingesetzt werden.${canEditCoreChecklists ? " Sie können die Checkliste jedoch wieder auf aktiv setzen." : ""}`} + sx={{ width: "100%" }} + /> + ) : ( + <Alert + color={"primary"} + message={`Inaktive Checklisten können nicht für Begehungen eingesetzt werden.${canEditChecklists ? " Sie können die Checkliste jedoch wieder auf aktiv setzen." : ""}`} + sx={{ width: "100%" }} + /> + ))} + {version.isCoreChecklist && !canEditCoreChecklists && ( + <Alert + color={"primary"} + message={`${!version.context.expandable ? "Exklusive " : ""}Kern-Checklisten können nur vom Landesamt erstellt werden.`} + sx={{ width: "100%" }} + /> + )} + </> + ); +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/history/VersionSheet.tsx b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/history/VersionSheet.tsx new file mode 100644 index 0000000000000000000000000000000000000000..14176212451e5e155463a220a1d53cf59022bdec --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/components/checklistDefinition/sidebars/history/VersionSheet.tsx @@ -0,0 +1,466 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { ApiUserRole } from "@eshg/employee-portal-api/base"; +import { + ApiChecklistDefinition, + ApiChecklistDefinitionVersion, +} from "@eshg/employee-portal-api/inspection"; +import { Alert } from "@eshg/lib-portal/components/Alert"; +import { + Snackbar, + useSnackbar, +} from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; +import { formatDateTime } from "@eshg/lib-portal/formatters/dateTime"; +import { + CheckCircle, + CloudSync, + CloudUpload, + CopyAll, + CropFree, + Edit, + FactCheckOutlined, +} from "@mui/icons-material"; +import { Sheet, Stack, Typography } from "@mui/joy"; +import { SxProps } from "@mui/joy/styles/types"; +import { UseMutateAsyncFunction } from "@tanstack/react-query"; +import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"; +import { useRouter } from "next/navigation"; +import { isEmpty, isNonNullish } from "remeda"; + +import { + FormChecklistDefinitionVersion, + useAddChecklistDefinitionVersion, + useEditDraftChecklistDefinitionVersion, +} from "@/lib/businessModules/inspection/api/mutations/checklistDefinition"; +import { showPublishChecklistDefinitionDialog } from "@/lib/businessModules/inspection/components/checklistDefinition/helpers/helpers"; +import { + showUpdateRepoMenuEntry, + showUploadRepoMenuEntry, +} from "@/lib/businessModules/inspection/components/checklistDefinition/overview/columns"; +import { ActiveChecklistIcon } from "@/lib/businessModules/inspection/components/icons/ActiveChecklistIcon"; +import { CorechecklistIcon } from "@/lib/businessModules/inspection/components/icons/CorechecklistIcon"; +import { EditDraftIcon } from "@/lib/businessModules/inspection/components/icons/EditDraftIcon"; +import { ExclusiveCorechecklistIcon } from "@/lib/businessModules/inspection/components/icons/ExclusiveCorechecklistIcon"; +import { InactiveChecklistIcon } from "@/lib/businessModules/inspection/components/icons/InactiveChecklistIcon"; +import { routes } from "@/lib/businessModules/inspection/shared/routes"; +import { + ActionsItem, + ActionsMenu, +} from "@/lib/shared/components/buttons/ActionsMenu"; +import { ConfirmationDialogProps } from "@/lib/shared/components/confirmationDialog/ConfirmationDialog"; +import { useConfirmationDialog } from "@/lib/shared/components/confirmationDialog/ConfirmationDialogProvider"; +import { useHasUserRolesCheck } from "@/lib/shared/hooks/useAccessControl"; + +export function VersionSheet({ + definition, + version, + nameChange, + isCurrentVersion, + onUploadCldClick, + onUpdateCldClick, +}: Readonly<{ + definition: ApiChecklistDefinition; + version: ApiChecklistDefinitionVersion; + isCurrentVersion: boolean; + nameChange?: string; + onUploadCldClick: () => void; + onUpdateCldClick: () => void; +}>) { + const snackbar = useSnackbar(); + const router = useRouter(); + const { openConfirmationDialog } = useConfirmationDialog(); + const [ + canEditChecklists, + canEditCoreChecklists, + canUploadRepoChecklists, + canUploadRepoCoreChecklists, + ] = useHasUserRolesCheck([ + ApiUserRole.InspectionChecklistdefinitionsWrite, + ApiUserRole.InspectionCorechecklistdefinitionsEdit, + ApiUserRole.InspectionCentralrepositoryWrite, + ApiUserRole.InspectionCentralrepositoryWriteCorechecklists, + ]); + const { mutateAsync: editDraftCldVersion } = + useEditDraftChecklistDefinitionVersion(); + const { mutateAsync: addCldVersion } = useAddChecklistDefinitionVersion(); + const modifiedBy = + !isEmpty(version.modifiedBy?.firstName) && + !isEmpty(version.modifiedBy?.lastName) + ? `${version.modifiedBy!.firstName} ${version.modifiedBy!.lastName}` + : "Unbekannter Benutzer"; + const actionItems: ActionsItem[] = generateActionItems( + definition, + version, + snackbar, + router, + isCurrentVersion, + { + canEditCoreChecklists, + canEditChecklists, + canUploadRepoChecklists, + canUploadRepoCoreChecklists, + }, + { + editDraftCldVersion, + addCldVersion, + openConfirmationDialog, + onUploadCldClick, + onUpdateCldClick, + }, + ); + + function handleSheetClicked() { + if (!isCurrentVersion) { + router.push( + routes.checklists.definitions.viewVersion( + version.context.defId, + version.context.id, + ), + ); + } + } + + let VersionInfoTitle = `Lokal ${version.context.version}`; + if (isNonNullish(version.context.repositoryVersion)) { + VersionInfoTitle += `, Remote ${version.context.repositoryVersion}`; + } + + return ( + <Sheet + sx={{ + padding: 2, + borderRadius: (theme) => theme.radius.lg, + border: "1px solid", + borderColor: "#636B744D", + "&:hover": { + cursor: () => (!isCurrentVersion ? "pointer" : undefined), + backgroundColor: (theme) => theme.palette.neutral.plainHoverBg, + }, + }} + onClick={handleSheetClicked} + > + <Stack direction="column" gap={2}> + <Stack direction="row" gap={2}> + <Stack direction="column"> + <Stack + sx={{ + padding: 1, + backgroundColor: (theme) => theme.palette.background.level1, + borderRadius: "5px", + }} + > + <VersionIcon version={version} /> + </Stack> + </Stack> + <Stack direction="column" gap={2}> + <VersionInfo + title={VersionInfoTitle} + description={`Zuletzt bearbeitet am ${formatDateTime(version.context.lastModified)} von ${modifiedBy}`} + /> + </Stack> + {actionItems.length > 0 && ( + <Stack direction="column" gap={2}> + <ActionsMenu actionItems={actionItems} /> + </Stack> + )} + </Stack> + {nameChange && ( + <Stack direction="row"> + <Alert + color={"primary"} + message={`Die Checkliste wurde umbenannt zu “${nameChange}â€.`} + sx={{ width: "100%" }} + /> + </Stack> + )} + </Stack> + </Sheet> + ); +} + +function VersionInfo({ + title, + description, + sx, +}: Readonly<{ + title: string; + description?: string; + sx?: SxProps; +}>) { + return ( + <Stack direction="column" gap={0.5} sx={sx}> + <Typography level="title-md" fontWeight="600"> + {title} + </Typography> + {description && ( + <Typography level="body-md" fontWeight="400" textColor="text.secondary"> + {description} + </Typography> + )} + </Stack> + ); +} + +function VersionIcon({ + version, +}: Readonly<{ + version: ApiChecklistDefinitionVersion; +}>) { + if (!version.context.published) { + return ( + <EditDraftIcon + aria-hidden={false} + titleAccess="Entwurf" + aria-label="Entwurf" + /> + ); + } else if (version.context.deleted) { + return ( + <InactiveChecklistIcon + aria-hidden={false} + titleAccess="inaktive Checkliste" + aria-label="inaktive Checkliste" + /> + ); + } else if (version.isCoreChecklist) { + return version.context.expandable ? ( + <CorechecklistIcon + aria-hidden={false} + titleAccess="Kern-Checkliste" + aria-label="Kern-Checkliste" + /> + ) : ( + <ExclusiveCorechecklistIcon + aria-hidden={false} + titleAccess="Exklusive Kern-Checkliste" + aria-label="Exklusive Kern-Checkliste" + /> + ); + } else { + return ( + <FactCheckOutlined + aria-hidden={false} + titleAccess="Checkliste" + aria-label="Checkliste" + /> + ); + } +} + +function generateActionItems( + definition: ApiChecklistDefinition, + version: ApiChecklistDefinitionVersion, + snackbar: Snackbar, + router: AppRouterInstance, + isCurrentVersion: boolean, + permissions: { + canEditChecklists: boolean; + canEditCoreChecklists: boolean; + canUploadRepoChecklists: boolean; + canUploadRepoCoreChecklists: boolean; + }, + { + editDraftCldVersion, + addCldVersion, + openConfirmationDialog, + onUploadCldClick, + onUpdateCldClick, + }: { + onUploadCldClick: () => void; + onUpdateCldClick: () => void; + editDraftCldVersion: UseMutateAsyncFunction< + ApiChecklistDefinitionVersion, + Error, + { + versionId: string; + cldVersion: + | FormChecklistDefinitionVersion + | ApiChecklistDefinitionVersion; + }, + unknown + >; + addCldVersion: UseMutateAsyncFunction< + ApiChecklistDefinitionVersion, + Error, + { + defId: string; + cldVersion: + | FormChecklistDefinitionVersion + | ApiChecklistDefinitionVersion; + }, + unknown + >; + openConfirmationDialog: ( + confirmationDialog: Omit<ConfirmationDialogProps, "open" | "onClose"> & { + onClose?: ConfirmationDialogProps["onClose"]; + }, + ) => void; + }, +) { + const actionItems: ActionsItem[] = []; + if (!isCurrentVersion) return actionItems; + + const published = version.context.published; + const hideEdit = + !permissions.canEditChecklists || + (version.isCoreChecklist && !permissions.canEditCoreChecklists); + + if (!published) { + actionItems.push( + ...(hideEdit + ? [ + { + label: "Anzeigen", + onClick: routes.checklists.definitions.viewVersion( + version.context.defId, + version.context.id, + ), + startDecorator: <CropFree />, + }, + ] + : [ + { + label: "Bearbeiten", + onClick: routes.checklists.definitions.newVersion( + version.context.defId, + version.context.id, + ), + startDecorator: <Edit />, + }, + { + label: "Veröffentlichen", + onClick: () => + showPublishChecklistDefinitionDialog( + openConfirmationDialog, + version.context.name, + async () => { + await editDraftCldVersion( + { + versionId: version.context.id, + cldVersion: { + ...version, + context: { ...version.context, published: true }, + }, + }, + { + onSuccess: () => { + snackbar.confirmation( + "Die Checkliste wurde veröffentlicht und kann nun eingesetzt werden.", + ); + router.push(routes.checklists.definitions.index); + }, + }, + ); + }, + ), + startDecorator: <CheckCircle />, + }, + ]), + // { + // label: "Löschen", + // onClick: () => { + // snackbar.notification("Noch nicht implementiert."); + // }, + // color: "danger" as ColorPaletteProp, + // startDecorator: <Delete />, + // }, + ); + } else { + // published === true + actionItems.push( + { + label: "Anzeigen", + onClick: routes.checklists.definitions.viewVersion( + version.context.defId, + version.context.id, + ), + startDecorator: <CropFree />, + }, + ...(hideEdit + ? [] + : [ + { + label: "Für neue Version nutzen", + onClick: routes.checklists.definitions.newVersion( + version.context.defId, + version.context.id, + ), + startDecorator: <CopyAll />, + }, + ...(version.context.deleted + ? [ + { + label: "Aktiv stellen", + onClick: async () => { + await addCldVersion( + { + defId: version.context.defId, + cldVersion: { + ...version, + context: { + ...version.context, + published: true, + deleted: false, + }, + }, + }, + { + onSuccess: () => + router.push(routes.checklists.definitions.index), + }, + ); + }, + startDecorator: <ActiveChecklistIcon />, + }, + ] + : [ + { + label: "Inaktiv stellen", + onClick: async () => { + await addCldVersion( + { + defId: version.context.defId, + cldVersion: { + ...version, + context: { + ...version.context, + published: true, + deleted: true, + }, + }, + }, + { + onSuccess: () => + router.push(routes.checklists.definitions.index), + }, + ); + }, + startDecorator: <InactiveChecklistIcon />, + }, + ]), + ]), + ...(showUploadRepoMenuEntry(definition, permissions) + ? [ + { + label: "Hochladen", + onClick: onUploadCldClick, + startDecorator: <CloudUpload />, + }, + ] + : []), + ...(showUpdateRepoMenuEntry(definition, permissions) + ? [ + { + label: "Aktualisieren", + onClick: () => onUpdateCldClick, + startDecorator: <CloudSync />, + }, + ] + : []), + ); + } + return actionItems; +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/facility/pending/PendingFacilities.tsx b/employee-portal/src/lib/businessModules/inspection/components/facility/pending/PendingFacilities.tsx index 554b3b3b67ebf94d5831812bcd30234463d9d8e8..59acf3dd579f7dba2b25ab9ca7c9aec07278272d 100644 --- a/employee-portal/src/lib/businessModules/inspection/components/facility/pending/PendingFacilities.tsx +++ b/employee-portal/src/lib/businessModules/inspection/components/facility/pending/PendingFacilities.tsx @@ -7,7 +7,6 @@ import { Stack, Typography } from "@mui/joy"; -import { NewFacilityButton } from "@/lib/businessModules/inspection/components/facility/pending/NewFacilityButton"; import { PendingFacilitiesOfflineTable } from "@/lib/businessModules/inspection/components/facility/pending/PendingFacilitiesOfflineTable"; import { PendingFacilitiesTable } from "@/lib/businessModules/inspection/components/facility/pending/PendingFacilitiesTable"; import { SearchParams } from "@/lib/shared/helpers/searchParams"; @@ -31,9 +30,6 @@ export function PendingFacilities( return ( <Stack spacing={3}> - <Stack direction="row" spacing={3} justifyContent="end"> - <NewFacilityButton /> - </Stack> <PendingFacilitiesTable filter={props.searchParams} /> </Stack> ); diff --git a/employee-portal/src/lib/businessModules/inspection/components/facility/pending/PendingFacilitiesTable.tsx b/employee-portal/src/lib/businessModules/inspection/components/facility/pending/PendingFacilitiesTable.tsx index 2c860a8f9d596d5088a6e6bed3bf8fb3634f94b5..d134b358b213364e5b2134f9c2ee8996da1131b9 100644 --- a/employee-portal/src/lib/businessModules/inspection/components/facility/pending/PendingFacilitiesTable.tsx +++ b/employee-portal/src/lib/businessModules/inspection/components/facility/pending/PendingFacilitiesTable.tsx @@ -5,13 +5,15 @@ "use client"; +import { ApiObjectType } from "@eshg/employee-portal-api/inspection"; import { optionsFromRecord } from "@eshg/lib-portal/components/formFields/SelectOptions"; -import { Stack } from "@mui/joy"; -import { useState } from "react"; +import { addDays, formatISO } from "date-fns"; +import { useMemo, useState } from "react"; import { procedureStatusNames } from "@/lib/baseModule/api/procedures/enums"; import { useGetPendingFacilities } from "@/lib/businessModules/inspection/api/queries/facility"; import { useGetObjectTypes } from "@/lib/businessModules/inspection/api/queries/objectTypes"; +import { NewFacilityButton } from "@/lib/businessModules/inspection/components/facility/pending/NewFacilityButton"; import { PendingFacilitiesIncidentsSidebar } from "@/lib/businessModules/inspection/components/facility/pending/PendingFacilitiesIncidentsSidebar"; import { inspectionPendingFacilityKindNames, @@ -20,11 +22,21 @@ import { } from "@/lib/businessModules/inspection/shared/enums"; import { useIsOfflineFeatureEnabled } from "@/lib/businessModules/inspection/shared/offline/useIsOfflineFeatureEnabled"; import { PendingFacilitiesFilters } from "@/lib/businessModules/inspection/shared/types"; +import { ButtonBar } from "@/lib/shared/components/buttons/ButtonBar"; +import { FilterButton } from "@/lib/shared/components/buttons/FilterButton"; +import { FilterSettings } from "@/lib/shared/components/filterSettings/FilterSettings"; +import { FilterSettingsSheet } from "@/lib/shared/components/filterSettings/FilterSettingsSheet"; +import { FilterDefinition } from "@/lib/shared/components/filterSettings/models/FilterDefinition"; +import { FilterValue } from "@/lib/shared/components/filterSettings/models/FilterValue"; +import { + FilterSettingsStateProvider, + useFilterSettings, +} from "@/lib/shared/components/filterSettings/useFilterSettings"; +import { useSearchParamStateProvider } from "@/lib/shared/components/filterSettings/useSearchParamStateProvider"; import { Pagination } from "@/lib/shared/components/pagination/Pagination"; import { DataTable } from "@/lib/shared/components/table/DataTable"; import { TablePage } from "@/lib/shared/components/table/TablePage"; import { TableSheet } from "@/lib/shared/components/table/TableSheet"; -import { SingleSelectFilter } from "@/lib/shared/components/tableFilters/SingleSelectFilter"; import { TextInputFilter } from "@/lib/shared/components/tableFilters/TextInputFilter"; import { useTableControl } from "@/lib/shared/hooks/searchParams/useTableControl"; @@ -39,15 +51,89 @@ type UserActivityState = const initialUserActivity: UserActivityState = { type: "view-table" }; +function createFilterDefinitions( + objectTypes: ApiObjectType[], +): FilterDefinition[] { + const objectTypeOptions = objectTypes.map((o) => ({ + label: o.name, + value: o.id, + })); + + return [ + { + type: "EnumSingle", + key: "kind", + name: "Art", + options: optionsFromRecord(inspectionPendingFacilityKindNames), + }, + { + type: "EnumSingle", + key: "objectTypeId", + name: "Objekttyp", + options: objectTypeOptions, + }, + { + type: "Enum", + key: "status", + name: "Status", + options: optionsFromRecord(procedureStatusNames), + }, + { + type: "Enum", + key: "type", + name: "Typ", + options: optionsFromRecord(inspectionTypeNames), + }, + { + type: "Enum", + key: "phase", + name: "Phase", + options: optionsFromRecord(inspectionPhaseNames), + }, + { + type: "Date", + key: "isBefore", + name: "Begehung vor", + }, + { + type: "Date", + key: "isAfter", + name: "Begehung nach", + }, + ]; +} + export function PendingFacilitiesTable( props: Readonly<{ filter: PendingFacilitiesFilters }>, ) { const isOfflineEnabled = useIsOfflineFeatureEnabled(); + const { data: objectTypes } = useGetObjectTypes(); - const { data: procedures, isFetching } = useGetPendingFacilities( - props.filter, + const filterDefinitions = createFilterDefinitions(objectTypes); + const paramStateProvider = useSearchParamStateProvider( + filterDefinitions, + true, ); - const { data: objectTypes } = useGetObjectTypes(); + const { stateProvider, filter } = usePendingFacilitiesFilterState({ + stateProvider: paramStateProvider, + defaults: [ + { + type: "Enum", + key: "phase", + selectedValues: ["NEW", "PLANNING", "READY_FOR_EXECUTION"], + }, + { + type: "Date", + key: "isBefore", + selectedValue: formatISO(addDays(new Date(), 14), { + representation: "date", + }), + }, + ], + filter: props.filter, + }); + + const { data: procedures, isFetching } = useGetPendingFacilities(filter); const tableControl = useTableControl({ serverSideSorting: true }); const columns = createPendingFacilitiesColumns( @@ -58,10 +144,13 @@ export function PendingFacilitiesTable( const [userActivity, setUserActivity] = useState<UserActivityState>(initialUserActivity); - const objectTypeOptions = objectTypes.map((o) => ({ - label: o.name, - value: o.id, - })); + const filterSettings = useFilterSettings({ + definitions: filterDefinitions, + stateProvider, + // eslint-disable-next-line @typescript-eslint/no-empty-function + onValuesSubmit: (_values) => {}, + showSearch: false, + }); function handleSidebarClosed() { setUserActivity(initialUserActivity); @@ -82,62 +171,41 @@ export function PendingFacilitiesTable( <> <TablePage controls={ - <Stack direction="row" flexWrap="wrap" gap={1}> - <SingleSelectFilter - searchParamName="kind" - placeholder="Art" - options={optionsFromRecord(inspectionPendingFacilityKindNames)} - tableControl={tableControl} - /> - <SingleSelectFilter - searchParamName="objectTypeId" - placeholder="Objekt-Typ" - options={objectTypeOptions} - tableControl={tableControl} - /> - <TextInputFilter - searchParamName="name" - placeholder="Name" - sx={{ flexGrow: 1 }} - tableControl={tableControl} - /> - <TextInputFilter - searchParamName="postalCode" - placeholder="PLZ" - sx={{ maxWidth: "5rem" }} - tableControl={tableControl} - /> - <TextInputFilter - searchParamName="city" - placeholder="Stadt" - sx={{ flexGrow: 1 }} - tableControl={tableControl} - /> - <TextInputFilter - searchParamName="street" - placeholder="Straße" - sx={{ flexGrow: 1 }} - tableControl={tableControl} - /> - <SingleSelectFilter - searchParamName="status" - placeholder="Status" - options={optionsFromRecord(procedureStatusNames)} - tableControl={tableControl} - /> - <SingleSelectFilter - searchParamName="type" - placeholder="Typ" - options={optionsFromRecord(inspectionTypeNames)} - tableControl={tableControl} - /> - <SingleSelectFilter - searchParamName="phase" - placeholder="Phase" - options={optionsFromRecord(inspectionPhaseNames)} - tableControl={tableControl} - /> - </Stack> + <ButtonBar + left={ + <> + <FilterButton {...filterSettings.filterButtonProps} /> + <TextInputFilter + searchParamName="name" + placeholder="Name" + tableControl={tableControl} + /> + <TextInputFilter + searchParamName="postalCode" + placeholder="PLZ" + tableControl={tableControl} + /> + <TextInputFilter + searchParamName="city" + placeholder="Stadt" + tableControl={tableControl} + /> + <TextInputFilter + searchParamName="street" + placeholder="Straße" + tableControl={tableControl} + /> + </> + } + right={<NewFacilityButton />} + /> + } + filterSettings={ + filterSettings.filterSettingsVisible && ( + <FilterSettingsSheet {...filterSettings.filterSettingsSheetProps}> + <FilterSettings {...filterSettings.filterSettingsProps} /> + </FilterSettingsSheet> + ) } > <TableSheet @@ -170,3 +238,56 @@ export function PendingFacilitiesTable( </> ); } + +function usePendingFacilitiesFilterState(options: { + stateProvider: FilterSettingsStateProvider; + filter: PendingFacilitiesFilters; + defaults: FilterValue[]; +}) { + const { activeValues, setActiveValues, ...rest } = options.stateProvider; + const [touched, setTouched] = useState(activeValues.length > 0); + + const stateProvider: FilterSettingsStateProvider = { + activeValues: touched ? activeValues : options.defaults, + setActiveValues: (values) => { + setTouched(true); + setActiveValues(values); + }, + ...rest, + }; + + const filter: PendingFacilitiesFilters = useMemo( + () => ({ + ...options.filter, + ...(touched ? {} : activeValuesToFilters(options.defaults)), + }), + [options.filter, options.defaults, touched], + ); + + return { + stateProvider, + filter, + }; +} + +function activeValuesToFilters( + activeValues: FilterValue[], +): PendingFacilitiesFilters { + const filters = new Map<string, unknown>(); + + for (const value of activeValues) { + switch (value.type) { + case "Date": + case "EnumSingle": + filters.set(value.key, value.selectedValue); + break; + case "Enum": + filters.set(value.key, value.selectedValues); + break; + case "Number": + break; + } + } + + return Object.fromEntries(filters); +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/icons/ActiveChecklistIcon.tsx b/employee-portal/src/lib/businessModules/inspection/components/icons/ActiveChecklistIcon.tsx new file mode 100644 index 0000000000000000000000000000000000000000..67c339f846c566329de8c184a6d18a6e23dd413f --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/components/icons/ActiveChecklistIcon.tsx @@ -0,0 +1,35 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { SvgIcon, SvgIconProps } from "@mui/joy"; + +export function ActiveChecklistIcon(props: SvgIconProps) { + return ( + <SvgIcon {...props}> + <svg + width="18" + height="16" + viewBox="0 0 18 16" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + <path + fill-rule="evenodd" + clip-rule="evenodd" + d="M1.8 0H16.2C17.19 0 18 0.794375 18 1.76528V7.70304H16.2V1.76528H1.8V14.1222H7.85455V15.8875H1.8C0.81 15.8875 0 15.0931 0 14.1222V1.76528C0 0.794375 0.81 0 1.8 0ZM7.85455 8.8264V7.06112H2.7V8.8264H7.85455ZM7.85455 3.53056H2.7V5.29584H7.85455V3.53056ZM2.7 10.5917H6.38182V12.357H2.7V10.5917Z" + fill="#171A1C" + /> + <path + d="M9.63084 12.9633L11.0672 11.5546L14.1637 14.5913L12.7273 16L9.63084 12.9633Z" + fill="#171A1C" + /> + <path + d="M12.7273 16L11.2909 14.5913L16.0934 9.88141L17.5298 11.2901L12.7273 16Z" + fill="#171A1C" + /> + </svg> + </SvgIcon> + ); +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/icons/CorechecklistIcon.tsx b/employee-portal/src/lib/businessModules/inspection/components/icons/CorechecklistIcon.tsx new file mode 100644 index 0000000000000000000000000000000000000000..487633ca715e202d38c3b11c8abf4112b92475e0 --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/components/icons/CorechecklistIcon.tsx @@ -0,0 +1,25 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { SvgIcon, SvgIconProps } from "@mui/joy"; + +export function CorechecklistIcon(props: SvgIconProps) { + return ( + <SvgIcon {...props}> + <svg + width="18" + height="18" + viewBox="0 0 18 18" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + <path + d="M9 0C4.041 0 0 4.041 0 9C0 13.959 4.041 18 9 18C13.959 18 18 13.959 18 9C18 4.041 13.959 0 9 0ZM9 16.2C5.031 16.2 1.8 12.969 1.8 9C1.8 5.031 5.031 1.8 9 1.8C12.969 1.8 16.2 5.031 16.2 9C16.2 12.969 12.969 16.2 9 16.2ZM11.7 9C11.7 10.494 10.494 11.7 9 11.7C7.506 11.7 6.3 10.494 6.3 9C6.3 7.506 7.506 6.3 9 6.3C10.494 6.3 11.7 7.506 11.7 9Z" + fill="#171A1C" + /> + </svg> + </SvgIcon> + ); +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/icons/EditDraftIcon.tsx b/employee-portal/src/lib/businessModules/inspection/components/icons/EditDraftIcon.tsx new file mode 100644 index 0000000000000000000000000000000000000000..fcc6b4f9b04c6264959b1dbb26ed0a70dd8fedee --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/components/icons/EditDraftIcon.tsx @@ -0,0 +1,31 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { SvgIcon, SvgIconProps } from "@mui/joy"; + +export function EditDraftIcon(props: SvgIconProps) { + return ( + <SvgIcon {...props}> + <svg + width="24" + height="24" + viewBox="0 0 24 24" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + <path + fill-rule="evenodd" + clip-rule="evenodd" + d="M4 3H20C21.1 3 22 3.9 22 5V7H20V5H4V19H12H20V17H22V19C22 20.1 21.1 21 20 21H12H4C2.9 21 2 20.1 2 19V5C2 3.9 2.9 3 4 3ZM10 7H5V9H10V7ZM10 11H5V13H10V11Z" + fill="#171A1C" + /> + <path + d="M12 17V13.925L17.525 8.425C17.675 8.275 17.8417 8.16667 18.025 8.1C18.2083 8.03333 18.3917 8 18.575 8C18.775 8 18.9667 8.0375 19.15 8.1125C19.3333 8.1875 19.5 8.3 19.65 8.45L20.575 9.375C20.7083 9.525 20.8125 9.69167 20.8875 9.875C20.9625 10.0583 21 10.2417 21 10.425C21 10.6083 20.9667 10.7958 20.9 10.9875C20.8333 11.1792 20.725 11.35 20.575 11.5L15.075 17H12ZM13.5 15.5H14.45L17.475 12.45L17.025 11.975L16.55 11.525L13.5 14.55V15.5ZM17.025 11.975L16.55 11.525L17.475 12.45L17.025 11.975Z" + fill="#171A1C" + /> + </svg> + </SvgIcon> + ); +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/icons/ExclusiveCorechecklistIcon.tsx b/employee-portal/src/lib/businessModules/inspection/components/icons/ExclusiveCorechecklistIcon.tsx new file mode 100644 index 0000000000000000000000000000000000000000..12d1a7f6328fce2aba37e70ba495104d7a6c6a98 --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/components/icons/ExclusiveCorechecklistIcon.tsx @@ -0,0 +1,27 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { SvgIcon, SvgIconProps } from "@mui/joy"; + +export function ExclusiveCorechecklistIcon(props: SvgIconProps) { + return ( + <SvgIcon {...props}> + <svg + width="17" + height="16" + viewBox="0 0 17 16" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + <path + fill-rule="evenodd" + clip-rule="evenodd" + d="M7.52158 0.515432C3.39749 0.779061 0.251681 4.35453 0.51531 8.47861C0.778939 12.6027 4.35441 15.7485 8.47849 15.4849L8.3828 13.9879C5.08203 14.1989 2.22325 11.6837 2.01225 8.38292C1.80126 5.08216 4.3165 2.22338 7.61727 2.01238C10.7924 1.80941 13.5585 4.12906 13.9523 7.24392L15.4848 7.5217C15.2211 3.39762 11.6457 0.251803 7.52158 0.515432ZM10.2455 7.85662C10.3249 9.09908 9.38603 10.1661 8.14357 10.2456C6.90111 10.325 5.83404 9.38616 5.75462 8.14369C5.67519 6.90123 6.61403 5.83416 7.8565 5.75474C9.09896 5.67531 10.166 6.61415 10.2455 7.85662ZM13.1073 14.2601C13.0418 14.2185 12.9582 14.2185 12.8928 14.2601L11.3468 15.2423C11.1965 15.3378 11.0058 15.204 11.0443 15.0302L11.4616 13.1471C11.4771 13.0772 11.4541 13.0043 11.4011 12.956L10.0028 11.6809C9.87422 11.5636 9.94644 11.3494 10.1198 11.3339L11.9414 11.1713C12.0162 11.1646 12.081 11.1165 12.1091 11.0468L12.8145 9.29483C12.8818 9.12777 13.1183 9.12777 13.1856 9.29483L13.891 11.0468C13.919 11.1165 13.9838 11.1646 14.0587 11.1713L15.8803 11.3339C16.0536 11.3494 16.1258 11.5636 15.9972 11.6809L14.5989 12.956C14.546 13.0043 14.5229 13.0772 14.5384 13.1471L14.9558 15.0302C14.9943 15.204 14.8035 15.3378 14.6532 15.2423L13.1073 14.2601Z" + fill="#171A1C" + /> + </svg> + </SvgIcon> + ); +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/icons/InactiveChecklistIcon.tsx b/employee-portal/src/lib/businessModules/inspection/components/icons/InactiveChecklistIcon.tsx new file mode 100644 index 0000000000000000000000000000000000000000..ee4543310a0a78c25f18a5edc16030df0190fe7c --- /dev/null +++ b/employee-portal/src/lib/businessModules/inspection/components/icons/InactiveChecklistIcon.tsx @@ -0,0 +1,33 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { SvgIcon, SvgIconProps } from "@mui/joy"; + +export function InactiveChecklistIcon(props: SvgIconProps) { + return ( + <SvgIcon {...props}> + <svg + width="16" + height="14" + viewBox="0 0 16 14" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + <path + fillRule="evenodd" + clipRule="evenodd" + d="M2 0.333984H14C14.825 0.333984 15.5 1.00065 15.5 1.81547V5.18247H14V1.81547H2V12.1858H7.04545V13.6673H2C1.175 13.6673 0.5 13.0007 0.5 12.1858V1.81547C0.5 1.00065 1.175 0.333984 2 0.333984ZM7.04545 7.74139V6.25991H2.75V7.74139H7.04545ZM7.04545 3.29695H2.75V4.77843H7.04545V3.29695ZM2.75 9.22287H5.81818V10.7044H2.75V9.22287Z" + fill="#171A1C" + /> + <path + fillRule="evenodd" + clipRule="evenodd" + d="M9.94752 7.00065L8.75053 8.18286L10.8457 10.2522L8.75031 12.3218L9.94729 13.504L12.0427 11.4344L14.137 13.5028L15.334 12.3206L13.2397 10.2522L15.3337 8.18402L14.1367 7.00181L12.0427 9.06998L9.94752 7.00065Z" + fill="#171A1C" + /> + </svg> + </SvgIcon> + ); +} diff --git a/employee-portal/src/lib/businessModules/inspection/components/inspection/planning/InspectionTabPlanning.tsx b/employee-portal/src/lib/businessModules/inspection/components/inspection/planning/InspectionTabPlanning.tsx index 9968339a24daf1f4aa0bb2cb1d70cfa3f196a97b..c45cae8f68c016e6cf93f8d99250cd09217b1fd9 100644 --- a/employee-portal/src/lib/businessModules/inspection/components/inspection/planning/InspectionTabPlanning.tsx +++ b/employee-portal/src/lib/businessModules/inspection/components/inspection/planning/InspectionTabPlanning.tsx @@ -254,7 +254,8 @@ function RightColumnElements({ /> {isPacklistsEnabled && ( <PacklistTile - readonly={isOffline || lockedByDifferentUser} + readonly={lockedByDifferentUser && !isOffline} + isOffline={isOffline} inspection={inspection} /> )} diff --git a/employee-portal/src/lib/businessModules/inspection/components/inspection/planning/packlist/PacklistTile.tsx b/employee-portal/src/lib/businessModules/inspection/components/inspection/planning/packlist/PacklistTile.tsx index 057a18f0fd7efa30a49bede917703f9d6942cb8a..8d38219584c7d0d50472ec0a87c2c48071350de6 100644 --- a/employee-portal/src/lib/businessModules/inspection/components/inspection/planning/packlist/PacklistTile.tsx +++ b/employee-portal/src/lib/businessModules/inspection/components/inspection/planning/packlist/PacklistTile.tsx @@ -26,11 +26,13 @@ import { InfoTileAddButton } from "@/lib/shared/components/infoTile/InfoTileAddB export interface PacklistTileProps { readonly?: boolean; + isOffline?: boolean; inspection: ApiInspection; } export function PacklistTile({ readonly, + isOffline, inspection, }: Readonly<PacklistTileProps>) { const queryClient = useQueryClient(); @@ -187,7 +189,7 @@ export function PacklistTile({ idx={idx} handleCheck={handleCheck} handleDeleteClick={handleDeleteClick} - readonly={readonly} + readonly={readonly ?? isOffline} /> ) ); diff --git a/employee-portal/src/lib/businessModules/inspection/shared/types.ts b/employee-portal/src/lib/businessModules/inspection/shared/types.ts index 428a153ee281a86f320c16e28389e287dbd4606c..52542c1acc99062ee40897dd2c777f2a095082fb 100644 --- a/employee-portal/src/lib/businessModules/inspection/shared/types.ts +++ b/employee-portal/src/lib/businessModules/inspection/shared/types.ts @@ -14,5 +14,10 @@ export type FacilityWebSearchFilters = Partial<Omit<SearchRequest, "sort">> & { }; export type PendingFacilitiesFilters = Partial< - Omit<GetPendingFacilitiesRequest, "sort"> -> & { sortField?: string; sortDirection?: string }; + Omit<GetPendingFacilitiesRequest, "sort" | "isBefore" | "isAfter"> +> & { + sortField?: string; + sortDirection?: string; + isBefore?: string; + isAfter?: string; +}; diff --git a/employee-portal/src/lib/businessModules/measlesProtection/api/clients.ts b/employee-portal/src/lib/businessModules/measlesProtection/api/clients.ts index 0c4e70e097eb1b6c7e18e99f2c7a7e5d9bb3092c..11913eb3ebffd963eb4174dd806b8097f8f9b4a4 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/api/clients.ts +++ b/employee-portal/src/lib/businessModules/measlesProtection/api/clients.ts @@ -9,6 +9,7 @@ import { AppointmentBookingApi, AppointmentTypeApi, ApprovalRequestApi, + ArchivingApi, Configuration, DraftProtectionProcedureApi, FileApi, @@ -109,3 +110,8 @@ export function useApprovalRequestApi() { const configuration = useConfiguration(); return new ApprovalRequestApi(configuration); } + +export function useArchivingApi() { + const configuration = useConfiguration(); + return new ArchivingApi(configuration); +} diff --git a/employee-portal/src/lib/businessModules/measlesProtection/api/models/AppointmentBlockGroup.ts b/employee-portal/src/lib/businessModules/measlesProtection/api/models/AppointmentBlockGroup.ts index 703ce829679a3f1417a308de0f5482201aeca7f3..33bbfe653bc499b277f59172b500aaeee08e8726 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/api/models/AppointmentBlockGroup.ts +++ b/employee-portal/src/lib/businessModules/measlesProtection/api/models/AppointmentBlockGroup.ts @@ -27,6 +27,18 @@ export interface AppointmentBlockGroup extends AppointmentBlockMeasles { export type AppointmentDurationsMeasles = Record<ApiAppointmentType, number>; +export function mapAppointmentBlock( + response: ApiGetAppointmentBlock, +): AppointmentBlockMeasles { + return { + ...mapBaseEntity(response), + start: response.start, + end: response.end, + numberOfFreeAppointments: response.numberOfFreeAppointments, + numberOfBookedAppointments: response.numberOfBookedAppointments, + }; +} + export function mapAppointmentBlockGroup( response: ApiGetAppointmentBlockGroup, ): AppointmentBlockGroup { @@ -53,15 +65,3 @@ export function mapAppointmentBlockGroup( appointmentBlocks: response.appointmentBlocks.map(mapAppointmentBlock), }; } - -export function mapAppointmentBlock( - response: ApiGetAppointmentBlock, -): AppointmentBlockMeasles { - return { - ...mapBaseEntity(response), - start: response.start, - end: response.end, - numberOfFreeAppointments: response.numberOfFreeAppointments, - numberOfBookedAppointments: response.numberOfBookedAppointments, - }; -} diff --git a/employee-portal/src/lib/businessModules/measlesProtection/api/mutations/archiving.ts b/employee-portal/src/lib/businessModules/measlesProtection/api/mutations/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..1773314df02f25e03176fa47184a7a8738c5a960 --- /dev/null +++ b/employee-portal/src/lib/businessModules/measlesProtection/api/mutations/archiving.ts @@ -0,0 +1,18 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useArchivingApi } from "@/lib/businessModules/measlesProtection/api/clients"; +import { + useBulkUpdateProceduresArchivingRelevanceTemplate, + useExportRelevantProceduresTemplate, +} from "@/lib/shared/api/mutations/archiving"; + +export function useBulkUpdateProceduresArchivingRelevance() { + return useBulkUpdateProceduresArchivingRelevanceTemplate(useArchivingApi); +} + +export function useExportRelevantProcedures() { + return useExportRelevantProceduresTemplate(useArchivingApi); +} diff --git a/employee-portal/src/lib/businessModules/measlesProtection/api/mutations/statusTransitionApi.ts b/employee-portal/src/lib/businessModules/measlesProtection/api/mutations/statusTransitionApi.ts index 72589fc10b3a81b2159a41074a79f985ea482294..3dc59002f73ff317a836472204961674f9ec081e 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/api/mutations/statusTransitionApi.ts +++ b/employee-portal/src/lib/businessModules/measlesProtection/api/mutations/statusTransitionApi.ts @@ -22,6 +22,7 @@ export function useCloseProcedure({ onError, }: MutationPassThrough<void, UseCloseProcedureRequest> = {}) { const statusTransitionApi = useStatusTransitionApi(); + return useHandledMutation({ mutationFn: (request: UseCloseProcedureRequest) => statusTransitionApi.close(request.procedureId), @@ -36,6 +37,7 @@ export function useReopenProcedure({ onError, }: MutationPassThrough<void, UseReopenProcedureRequest> = {}) { const statusTransitionApi = useStatusTransitionApi(); + return useHandledMutation({ mutationFn: (request: UseReopenProcedureRequest) => statusTransitionApi.reopen(request.procedureId), diff --git a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/apiQueryKeys.ts b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/apiQueryKeys.ts index 89a67adfc04d46b9cef3f2de4f7b9f14629f09bf..30618280c35786f0f27836cab72ab1bc76ecc5fd 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/apiQueryKeys.ts +++ b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/apiQueryKeys.ts @@ -32,3 +32,7 @@ export const progressEntryApiQueryKey = queryKeyFactory( export const fileApiQueryKey = queryKeyFactory( measlesProtectionApiQueryKey(["fileApi"]), ); + +export const archivingApiQueryKey = queryKeyFactory( + measlesProtectionApiQueryKey(["archivingApi"]), +); diff --git a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/appointmentTypeApi.ts b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/appointmentTypeApi.ts index 9f23a9a030300e5974927f54d095c66eed1c13e7..7dec2daa1b8809f84edf615b1b34226c5d995369 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/appointmentTypeApi.ts +++ b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/appointmentTypeApi.ts @@ -13,6 +13,7 @@ import { appointmentTypeApiQueryKey } from "./apiQueryKeys"; export function useGetAppointmentDurations() { const appointmentTypeApi = useAppointmentTypeApi(); + return useSuspenseQuery({ queryKey: appointmentTypeApiQueryKey(["getAppointmentTypes"]), queryFn: () => diff --git a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/archiving.ts b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..6af19e7495febf67d3dd8985d4ff6be5229ac2a5 --- /dev/null +++ b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/archiving.ts @@ -0,0 +1,43 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + GetArchivableProceduresRequest, + GetRelevantArchivableProceduresRequest, +} from "@eshg/employee-portal-api/businessProcedures"; + +import { useArchivingApi } from "@/lib/businessModules/measlesProtection/api/clients"; +import { archivingApiQueryKey } from "@/lib/businessModules/measlesProtection/api/queries/apiQueryKeys"; +import { + useGetArchivableProceduresTemplate, + useGetArchivingConfigurationTemplate, + useGetRelevantArchivableProceduresTemplate, +} from "@/lib/shared/api/queries/archiving"; + +export function useGetArchivingConfiguration() { + return useGetArchivingConfigurationTemplate( + useArchivingApi, + archivingApiQueryKey, + ); +} +export function useGetArchivableProcedures( + request: GetArchivableProceduresRequest, +) { + return useGetArchivableProceduresTemplate( + useArchivingApi, + archivingApiQueryKey, + request, + ); +} + +export function useGetRelevantArchivableProcedures( + request: GetRelevantArchivableProceduresRequest, +) { + return useGetRelevantArchivableProceduresTemplate( + useArchivingApi, + archivingApiQueryKey, + request, + ); +} diff --git a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/files.ts b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/files.ts index 654bb5a7c26c27811b07854c12296147fc9ee133..445fc76de1099a6ac0661aa22ae8dc06054fcfd5 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/files.ts +++ b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/files.ts @@ -20,14 +20,6 @@ export function useGetFile(fileId: string) { }); } -export function useDownloadFile(fileId: string) { - const fileApi = useFileApi(); - return useSuspenseQuery({ - queryFn: () => fileApi.downloadFile(fileId), - queryKey: measlesProtectionApiQueryKey(["files", "download", fileId]), - }); -} - export function useGetMetaDataHistory(fileId: string) { return useGetMetaDataHistoryTemplate(useFileApi, fileApiQueryKey, fileId); } diff --git a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/procedures.ts b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/procedures.ts index c216a719f8d05f09d17de6d8af662d371a1f088b..2b5313380dae59df05d72106cd23ccb6c8bb39cd 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/procedures.ts +++ b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/procedures.ts @@ -5,8 +5,8 @@ "use client"; -import { type ApiGetReferencePersonResponse } from "@eshg/employee-portal-api/base"; -import { useSuspenseQuery } from "@tanstack/react-query"; +import { ProtectionProcedureApi } from "@eshg/employee-portal-api/measlesProtection"; +import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; import { useProtectionProcedureApi } from "@/lib/businessModules/measlesProtection/api/clients"; import { ProcedureFilters } from "@/lib/businessModules/measlesProtection/components/procedures/proceduresTable/ProceduresTableFilters"; @@ -14,9 +14,8 @@ import { ProcedureFilters } from "@/lib/businessModules/measlesProtection/compon import { measlesProtectionApiQueryKey } from "./apiQueryKeys"; function mapTableFieldToSortField(sortBy?: string) { - if (!sortBy) { - return; - } + if (!sortBy) return; + switch (sortBy) { case "id": throw Error("Not implemented"); @@ -36,8 +35,9 @@ function mapTableFieldToSortField(sortBy?: string) { return "PROCEDURE_STATUS"; case "caseStatus": return "CASE_STATUS"; + default: + throw Error(`Unexpected sort field: ${sortBy}`); } - throw Error(`Unexpected sort field: ${sortBy}`); } interface PageRequest { @@ -46,14 +46,35 @@ interface PageRequest { sortBy?: string; sortOrder?: string; } + +export function getProcedureQuery( + protectionProcedureApi: ProtectionProcedureApi, + procedureId: string, +) { + return queryOptions({ + queryFn: ({ signal }) => + protectionProcedureApi.getProcedure(procedureId, { signal }), + queryKey: measlesProtectionApiQueryKey(["procedures", procedureId]), + }); +} + +export function useProcedureQuery(procedureId: string) { + const protectionProcedureApi = useProtectionProcedureApi(); + + return useSuspenseQuery( + getProcedureQuery(protectionProcedureApi, procedureId), + ); +} + export function useProceduresQuery( page: PageRequest, filters: ProcedureFilters, ) { - const measlesProtectionApi = useProtectionProcedureApi(); + const protectionProcedureApi = useProtectionProcedureApi(); + return useSuspenseQuery({ queryFn: ({ signal }) => - measlesProtectionApi.getProcedures( + protectionProcedureApi.getProcedures( page.pageNumber, page.pageSize, mapTableFieldToSortField(page.sortBy), @@ -87,31 +108,8 @@ function makeFiltersQueryKeyPart(filters: ProcedureFilters) { if (value instanceof Set) { return [key, Array.from(value).join(",")]; } + return [key, value]; }), ); } - -export function useProcedureQuery(procedureId: string) { - const measlesProtectionApi = useProtectionProcedureApi(); - return useSuspenseQuery({ - queryFn: ({ signal }) => - measlesProtectionApi.getProcedure(procedureId, { signal }), - queryKey: measlesProtectionApiQueryKey(["procedures", procedureId]), - }); -} - -export function useProceduresForPersonQuery( - person: ApiGetReferencePersonResponse, -) { - const measlesProtectionApi = useProtectionProcedureApi(); - return useSuspenseQuery({ - queryFn: async ({ signal }) => - measlesProtectionApi.getProceduresForPerson({ person }, { signal }), - queryKey: measlesProtectionApiQueryKey([ - "procedures", - "for-person", - person, - ]), - }); -} diff --git a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/proofRequestLetters.ts b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/proofRequestLetters.ts index 6a7d1d4b63413215ee7f595ae4b5015768a5f512..9027a05431ea47ba23caa7904593378ac63baee8 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/api/queries/proofRequestLetters.ts +++ b/employee-portal/src/lib/businessModules/measlesProtection/api/queries/proofRequestLetters.ts @@ -3,14 +3,17 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { useSuspenseQuery } from "@tanstack/react-query"; +import { ProofRequestLetterApi } from "@eshg/employee-portal-api/measlesProtection"; +import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; import { useProofRequestLetterApi } from "@/lib/businessModules/measlesProtection/api/clients"; import { measlesProtectionApiQueryKey } from "@/lib/businessModules/measlesProtection/api/queries/apiQueryKeys"; -export function useProofRequestLettersQuery(procedureId: string) { - const proofRequestLetterApi = useProofRequestLetterApi(); - return useSuspenseQuery({ +export function getProofRequestLettersQuery( + proofRequestLetterApi: ProofRequestLetterApi, + procedureId: string, +) { + return queryOptions({ queryFn: ({ signal }) => proofRequestLetterApi.getProofRequestLetters(procedureId, { signal, @@ -22,3 +25,11 @@ export function useProofRequestLettersQuery(procedureId: string) { ]), }); } + +export function useProofRequestLettersQuery(procedureId: string) { + const proofRequestLetterApi = useProofRequestLetterApi(); + + return useSuspenseQuery( + getProofRequestLettersQuery(proofRequestLetterApi, procedureId), + ); +} diff --git a/employee-portal/src/lib/businessModules/measlesProtection/components/appointmentBlocks/ValidateAppointmentBlock.ts b/employee-portal/src/lib/businessModules/measlesProtection/components/appointmentBlocks/ValidateAppointmentBlock.ts index 6b509e454f1b849a0f2f549fa5f0d1665d3033cd..756ae77d139f3b13ddbad82354662d07aa682238 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/components/appointmentBlocks/ValidateAppointmentBlock.ts +++ b/employee-portal/src/lib/businessModules/measlesProtection/components/appointmentBlocks/ValidateAppointmentBlock.ts @@ -11,7 +11,7 @@ import { FormikErrors } from "formik"; import { isEmpty } from "remeda"; import { AppointmentDurationsMeasles } from "@/lib/businessModules/measlesProtection/api/models/AppointmentBlockGroup"; -import { getAppointmentDurationInMinutes } from "@/lib/businessModules/measlesProtection/shared/helper"; +import { getAppointmentDurationInMinutes } from "@/lib/businessModules/measlesProtection/shared/helpers"; import { AppointmentBlockGroupValuesWithDays } from "@/lib/shared/components/appointmentBlocks/AppointmentBlockFormWithDays"; import { calculateAppointmentsPerBlock } from "@/lib/shared/components/appointmentBlocks/AppointmentCountWithDays"; import { toLocalDateTime } from "@/lib/shared/helpers/dateTime"; diff --git a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/createProceduresForm/NewPersonButton.tsx b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/createProceduresForm/NewPersonButton.tsx index f8d5d40acccf8501a3cc273b5e659c998c9167e4..a0bea3ab9a1ca8013f427479f70ab027bf5da13a 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/createProceduresForm/NewPersonButton.tsx +++ b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/createProceduresForm/NewPersonButton.tsx @@ -19,7 +19,7 @@ import { useProceduresForPersonSearch, } from "@/lib/businessModules/measlesProtection/api/mutations/procedures"; import { reportingReasonNames } from "@/lib/businessModules/measlesProtection/components/procedures/constants"; -import { mapToApiPersonAddress } from "@/lib/businessModules/measlesProtection/shared/helper"; +import { mapToApiPersonAddress } from "@/lib/businessModules/measlesProtection/shared/helpers"; import { routes } from "@/lib/businessModules/measlesProtection/shared/routes"; import { LegacyPersonSidebar } from "@/lib/shared/components/legacyPersonSidebar/LegacyPersonSidebar"; import { diff --git a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/NewCustodianButton.tsx b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/NewCustodianButton.tsx index 95363c81052012b5a21f869c51924450be3763e4..89241cd858b10bf17d9da4349472d08dfddfa499 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/NewCustodianButton.tsx +++ b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/NewCustodianButton.tsx @@ -13,7 +13,7 @@ import { Add } from "@mui/icons-material"; import { Button } from "@mui/joy"; import { DetailCard } from "@/lib/businessModules/measlesProtection/components/procedures/procedureDetails/DetailCard"; -import { mapToApiPersonAddress } from "@/lib/businessModules/measlesProtection/shared/helper"; +import { mapToApiPersonAddress } from "@/lib/businessModules/measlesProtection/shared/helpers"; import { LegacyPerson, LegacyPersonFormConfig, diff --git a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/ProofTab.tsx b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/ProofTab.tsx index 7032d737fe9035a2b65deee5fa776a01747ea184..307507a96a27516a4402a2cc407812b36b4272fe 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/ProofTab.tsx +++ b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/ProofTab.tsx @@ -9,16 +9,22 @@ import { ApiMeaslesProtectionFeature, ApiMeaslesProtectionProcedure, ApiMonetaryFine, + ApiProofRequestLetter, ApiProofSubmission, ApiSubmissionResult, } from "@eshg/employee-portal-api/measlesProtection"; import { formatDate } from "@eshg/lib-portal/formatters/dateTime"; import { Add } from "@mui/icons-material"; import { Button, Grid, Stack } from "@mui/joy"; +import { useSuspenseQueries } from "@tanstack/react-query"; +import { + useProofRequestLetterApi, + useProtectionProcedureApi, +} from "@/lib/businessModules/measlesProtection/api/clients"; import { useIsNewFeatureEnabled } from "@/lib/businessModules/measlesProtection/api/queries/featureTogglesApi"; -import { useProcedureQuery } from "@/lib/businessModules/measlesProtection/api/queries/procedures"; -import { useProofRequestLettersQuery } from "@/lib/businessModules/measlesProtection/api/queries/proofRequestLetters"; +import { getProcedureQuery } from "@/lib/businessModules/measlesProtection/api/queries/procedures"; +import { getProofRequestLettersQuery } from "@/lib/businessModules/measlesProtection/api/queries/proofRequestLetters"; import { submissionResultLabels } from "@/lib/businessModules/measlesProtection/components/procedures/constants"; import { AccessRestrictionLetterSidebar } from "@/lib/businessModules/measlesProtection/components/procedures/procedureDetails/AccessRestrictionLetterSidebar"; import { @@ -45,7 +51,7 @@ import { AppointmentCard } from "./proof/AppointmentCard"; import { ProofTabEntry } from "./proof/ProofTabEntry"; import { ProofTabFileCard } from "./proof/ProofTabFileCard"; -export function ProofTab({ id }: Readonly<{ id: string }>) { +export function ProofTab({ procedureId }: Readonly<{ procedureId: string }>) { const [_openProof, setOpenProof] = useSearchParam("add-proof", "boolean"); const [_openFine, setOpenFine] = useSearchParam("add-fine", "boolean"); const [_openAccessRestriction, setOpenAccessRestriction] = useSearchParam( @@ -58,7 +64,19 @@ export function ProofTab({ id }: Readonly<{ id: string }>) { "add-proof-request-letter", "boolean", ); - const procedure = useProcedureQuery(id).data; + const protectionProcedureApi = useProtectionProcedureApi(); + const proofRequestLetterApi = useProofRequestLetterApi(); + const [ + { data: procedure }, + { + data: { letters }, + }, + ] = useSuspenseQueries({ + queries: [ + getProcedureQuery(protectionProcedureApi, procedureId), + getProofRequestLettersQuery(proofRequestLetterApi, procedureId), + ], + }); const isEditAccessRestrictionEnabled = useIsNewFeatureEnabled( ApiMeaslesProtectionFeature.EditAccessRestriction, ); @@ -78,7 +96,7 @@ export function ProofTab({ id }: Readonly<{ id: string }>) { <AppointmentCard appointment={appointment} procedureClosed={procedureClosed} - procedureId={id} + procedureId={procedureId} /> </Grid> @@ -110,8 +128,9 @@ export function ProofTab({ id }: Readonly<{ id: string }>) { <Grid xxs={12} lg={6}> <ProofRequestLetterCard procedure={procedure} - onClick={() => setOpenProofRequestLetter(true)} procedureClosed={procedureClosed} + proofSubmissionLetters={letters} + onClick={() => setOpenProofRequestLetter(true)} /> </Grid> </Grid> @@ -119,16 +138,16 @@ export function ProofTab({ id }: Readonly<{ id: string }>) { <Grid xxs={12} lg={6} xxl={3}> <AdditionalInfoSection procedure={procedure} /> </Grid> - <AddAppointmentSidebar id={id} /> - <EditAppointmentSidebar id={id} /> - <ProofSidebar id={id} /> - <FineSidebar id={id} /> - <AccessRestrictionSidebar id={id} /> - <AccessRestrictionLetterSidebar id={id} /> + <AddAppointmentSidebar id={procedureId} /> + <EditAppointmentSidebar id={procedureId} /> + <ProofSidebar id={procedureId} /> + <FineSidebar id={procedureId} /> + <AccessRestrictionSidebar id={procedureId} /> + <AccessRestrictionLetterSidebar id={procedureId} /> {isEditAccessRestrictionEnabled && ( <EditAccessRestrictionSidebar procedure={procedure} /> )} - <ProofRequestLetterSidebar id={id} /> + <ProofRequestLetterSidebar id={procedureId} /> </Grid> ); } @@ -225,19 +244,18 @@ function FineCard({ } interface ProofRequestLetterCardProps { - procedure: ApiMeaslesProtectionProcedure; onClick: () => void; + procedure: ApiMeaslesProtectionProcedure; procedureClosed: boolean; + proofSubmissionLetters: ApiProofRequestLetter[]; } function ProofRequestLetterCard({ - procedure, onClick, + procedure, procedureClosed, + proofSubmissionLetters, }: Readonly<ProofRequestLetterCardProps>) { - const proofSubmissionLetters = - useProofRequestLettersQuery(procedure.id).data.letters ?? []; - return ( <DetailCard title={"Anschreiben Nachweisvorlage"} diff --git a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/helpers.ts b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/helpers.ts index 57c65dd17c68037fa7fdee6a82dc53fc608828e8..bc52ede49a4533f5f237f5f4f008de0df38320bd 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/helpers.ts +++ b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/procedureDetails/helpers.ts @@ -14,7 +14,7 @@ import { import { AlertProps as SharedAlertProps } from "@eshg/lib-portal/components/Alert"; import { isObjectType } from "remeda"; -import { isAdult } from "@/lib/businessModules/measlesProtection/shared/helper"; +import { isAdult } from "@/lib/businessModules/measlesProtection/shared/helpers"; export interface UpdateProcedureForm { reportData: { diff --git a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/ProceduresTableFilters.tsx b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/ProceduresTableFilters.tsx index e1f3dcca5b40f68a037831c44b4161b9b5aee7fe..6660419ebd5a6f4c01173aab2dd91967b4ed3238 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/ProceduresTableFilters.tsx +++ b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/ProceduresTableFilters.tsx @@ -28,10 +28,9 @@ import { FilterSettingsSheet } from "@/lib/shared/components/filterSettings/Filt import { FilterDefinition } from "@/lib/shared/components/filterSettings/models/FilterDefinition"; import { FilterValue } from "@/lib/shared/components/filterSettings/models/FilterValue"; import { useFilterSettings } from "@/lib/shared/components/filterSettings/useFilterSettings"; +import { useSearchParamStateProvider } from "@/lib/shared/components/filterSettings/useSearchParamStateProvider"; import { procedureStatusNames } from "@/lib/shared/components/procedures/constants"; -import { useSearchParamStateProvider } from "./useSearchParamStateProvider"; - type ProceduresFilterDefinition = FilterDefinition & { key: keyof ProcedureFilters; }; diff --git a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/ReopenProcedureModal.tsx b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/ReopenProcedureModal.tsx index 807c6f91eaf98062354f51fb00fda5c900b36d0b..636bcc81e677320af0724df0c987e66b0342dcd2 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/ReopenProcedureModal.tsx +++ b/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/ReopenProcedureModal.tsx @@ -7,61 +7,18 @@ import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; import { formatDate } from "@eshg/lib-portal/formatters/dateTime"; -import { Button, Grid, Stack, Typography, TypographyProps } from "@mui/joy"; -import { SxProps } from "@mui/joy/styles/types"; +import { Button, Stack } from "@mui/joy"; import { useState } from "react"; -import { multiLineEllipsis } from "@/lib/baseModule/theme/theme"; import { useReopenProcedure } from "@/lib/businessModules/measlesProtection/api/mutations/statusTransitionApi"; import { REOPEN_PROCEDURE_SUCCESS_MESSAGE } from "@/lib/businessModules/measlesProtection/components/procedures/procedureDetails/helpers"; import { useProceduresContext } from "@/lib/businessModules/measlesProtection/shared/ProceduresContext"; import { BaseModal } from "@/lib/shared/components/BaseModal"; import { OverlayBoundary } from "@/lib/shared/components/boundaries/OverlayBoundary"; - -interface ResponsiveTypographyProps extends TypographyProps { - linesToShow?: number; - sx?: SxProps; - value: string; -} - -function ResponsiveTypography({ - linesToShow = 1, - sx, - value, - ...typographyProps -}: ResponsiveTypographyProps) { - return ( - <Typography - sx={ - { - ...multiLineEllipsis(linesToShow), - ...sx, - } as SxProps - } - slotProps={{ - root: { - title: value, - }, - }} - {...typographyProps} - > - {value} - </Typography> - ); -} - -function DataField({ label, value }: { label: string; value: string }) { - return ( - <Grid container xxs={12}> - <Grid xxs={12} sm={3}> - <ResponsiveTypography level="body-md" sx={{ mr: 2 }} value={label} /> - </Grid> - <Grid xxs={12} sm={9}> - <ResponsiveTypography level="title-md" fontWeight="600" value={value} /> - </Grid> - </Grid> - ); -} +import { + DataField, + ResponsiveTypography, +} from "@/lib/shared/components/modal/DataField"; export function ReopenProcedureModalContent() { const snackbar = useSnackbar(); diff --git a/employee-portal/src/lib/businessModules/measlesProtection/shared/helper.ts b/employee-portal/src/lib/businessModules/measlesProtection/shared/helpers.ts similarity index 100% rename from employee-portal/src/lib/businessModules/measlesProtection/shared/helper.ts rename to employee-portal/src/lib/businessModules/measlesProtection/shared/helpers.ts diff --git a/employee-portal/src/lib/businessModules/schoolEntry/api/clients.ts b/employee-portal/src/lib/businessModules/schoolEntry/api/clients.ts index 1663f3544f6a8691db0392c89e6c07337998e564..c544d13de5ca4b182a6d5a8742008a499ed32542 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/api/clients.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/api/clients.ts @@ -7,6 +7,7 @@ import { AppointmentBlockApi, AppointmentTypeApi, ApprovalRequestApi, + ArchivingApi, Configuration, FileApi, InboxProcedureApi, @@ -92,3 +93,8 @@ export function useAppointmentTypeApi() { const configuration = useConfiguration(); return new AppointmentTypeApi(configuration); } + +export function useArchivingApi() { + const configuration = useConfiguration(); + return new ArchivingApi(configuration); +} diff --git a/employee-portal/src/lib/businessModules/schoolEntry/api/models/VaccinationStatus.ts b/employee-portal/src/lib/businessModules/schoolEntry/api/models/VaccinationStatus.ts index 3c9d19581d7692c278fe6c98938cb399b21cf38c..3d58d3aa1b732a4c73b2e8cb553d3c2e32da3e1e 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/api/models/VaccinationStatus.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/api/models/VaccinationStatus.ts @@ -4,6 +4,7 @@ */ import { + ApiBooleanWithUnknown, ApiOtherVaccination, ApiVaccinationSchemeValue, ApiVaccinationStatus, @@ -32,7 +33,7 @@ export interface VaccinationStatus extends Versioned { tbe?: number; otherVaccinations: ApiOtherVaccination[]; vaccinationPassPresented?: boolean; - perkombiHbv?: boolean; + perkombiHbv?: ApiBooleanWithUnknown; } export function mapVaccinationStatus( diff --git a/employee-portal/src/lib/businessModules/schoolEntry/api/models/WaitingRoom.ts b/employee-portal/src/lib/businessModules/schoolEntry/api/models/WaitingRoom.ts index 70e4ebd269f8e04bde692fa94d68f1e844b56308..f82df3ba87e6431788368bad22eef13cc67157ea 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/api/models/WaitingRoom.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/api/models/WaitingRoom.ts @@ -5,9 +5,18 @@ import { ApiWaitingRoom, + ApiWaitingRoomProcedure, ApiWaitingStatus, } from "@eshg/employee-portal-api/schoolEntry"; +import { + BaseEntity, + mapBaseEntity, +} from "@/lib/businessModules/schoolEntry/api/models/BaseEntity"; +import { + Person, + mapPerson, +} from "@/lib/businessModules/schoolEntry/api/models/Person"; import { Versioned, mapVersioned, @@ -16,6 +25,7 @@ import { export interface WaitingRoom extends Versioned { description?: string; status?: ApiWaitingStatus; + modifiedAt?: Date; } export function mapWaitingRoom(response: ApiWaitingRoom): WaitingRoom { @@ -25,3 +35,20 @@ export function mapWaitingRoom(response: ApiWaitingRoom): WaitingRoom { status: response.status, }; } + +export interface WaitingRoomProcedure extends BaseEntity { + readonly child: Person; + readonly waitingRoom: ApiWaitingRoom; + readonly modifiedAt: Date; +} + +export function mapWaitingRoomProcedure( + response: ApiWaitingRoomProcedure, +): WaitingRoomProcedure { + return { + ...mapBaseEntity(response), + child: mapPerson(response.child), + waitingRoom: response.waitingRoom, + modifiedAt: response.modifiedAt, + }; +} diff --git a/employee-portal/src/lib/businessModules/schoolEntry/api/mutations/archiving.ts b/employee-portal/src/lib/businessModules/schoolEntry/api/mutations/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..a6557b134b534b3db3b02076f03087223a29f5bb --- /dev/null +++ b/employee-portal/src/lib/businessModules/schoolEntry/api/mutations/archiving.ts @@ -0,0 +1,18 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useArchivingApi } from "@/lib/businessModules/schoolEntry/api/clients"; +import { + useBulkUpdateProceduresArchivingRelevanceTemplate, + useExportRelevantProceduresTemplate, +} from "@/lib/shared/api/mutations/archiving"; + +export function useBulkUpdateProceduresArchivingRelevance() { + return useBulkUpdateProceduresArchivingRelevanceTemplate(useArchivingApi); +} + +export function useExportRelevantProcedures() { + return useExportRelevantProceduresTemplate(useArchivingApi); +} diff --git a/employee-portal/src/lib/businessModules/schoolEntry/api/mutations/schoolEntryApi.ts b/employee-portal/src/lib/businessModules/schoolEntry/api/mutations/schoolEntryApi.ts index cd4e698fb1562983ac2c08d767ffdc4b44e83ed8..7bb3ff17b19d223edf67fec3bb5496386c067ddf 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/api/mutations/schoolEntryApi.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/api/mutations/schoolEntryApi.ts @@ -18,6 +18,7 @@ import { DeleteProcedureRequest, ImportCitizenListRequest, ImportSchoolListRequest, + ReopenProcedureRequest, UpdateAnamnesisRequest, UpdateChildDataRequest, UpdateDevelopmentScreeningResultRequest, @@ -306,6 +307,17 @@ export function useCloseProcedure() { }); } +export function useReopenProcedure() { + const schoolEntryApi = useSchoolEntryApi(); + const snackbar = useSnackbar(); + return useHandledMutation({ + mutationFn: (values: ReopenProcedureRequest) => + schoolEntryApi.reopenProcedureRaw(values).then(unwrapRawResponse), + onSuccess: () => + snackbar.confirmation("Vorgang erfolgreich wiedereröffnet."), + }); +} + export function useDeleteProcedure() { const schoolEntryApi = useSchoolEntryApi(); const snackbar = useSnackbar(); diff --git a/employee-portal/src/lib/businessModules/schoolEntry/api/queries/apiQueryKeys.ts b/employee-portal/src/lib/businessModules/schoolEntry/api/queries/apiQueryKeys.ts index 56f0a54b4b78c444975e9a308faf33fab534c7c5..d17f589ef453e5693031cf718cda75bdb5b3bd92 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/api/queries/apiQueryKeys.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/api/queries/apiQueryKeys.ts @@ -42,3 +42,7 @@ export const appointmentStaffApiQueryKey = queryKeyFactory( export const fileApiQueryKey = queryKeyFactory(apiQueryKey(["fileApi"])); export const configApiQueryKey = queryKeyFactory(apiQueryKey(["configApi"])); + +export const archivingApiQueryKey = queryKeyFactory( + apiQueryKey(["archivingApi"]), +); diff --git a/employee-portal/src/lib/businessModules/schoolEntry/api/queries/archiving.ts b/employee-portal/src/lib/businessModules/schoolEntry/api/queries/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..d57b266b11bd1879b73503175a1da6e257111989 --- /dev/null +++ b/employee-portal/src/lib/businessModules/schoolEntry/api/queries/archiving.ts @@ -0,0 +1,43 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + GetArchivableProceduresRequest, + GetRelevantArchivableProceduresRequest, +} from "@eshg/employee-portal-api/businessProcedures"; + +import { useArchivingApi } from "@/lib/businessModules/schoolEntry/api/clients"; +import { archivingApiQueryKey } from "@/lib/businessModules/schoolEntry/api/queries/apiQueryKeys"; +import { + useGetArchivableProceduresTemplate, + useGetArchivingConfigurationTemplate, + useGetRelevantArchivableProceduresTemplate, +} from "@/lib/shared/api/queries/archiving"; + +export function useGetArchivingConfiguration() { + return useGetArchivingConfigurationTemplate( + useArchivingApi, + archivingApiQueryKey, + ); +} +export function useGetArchivableProcedures( + request: GetArchivableProceduresRequest, +) { + return useGetArchivableProceduresTemplate( + useArchivingApi, + archivingApiQueryKey, + request, + ); +} + +export function useGetRelevantArchivableProcedures( + request: GetRelevantArchivableProceduresRequest, +) { + return useGetRelevantArchivableProceduresTemplate( + useArchivingApi, + archivingApiQueryKey, + request, + ); +} diff --git a/employee-portal/src/lib/businessModules/schoolEntry/api/queries/configApi.ts b/employee-portal/src/lib/businessModules/schoolEntry/api/queries/configApi.ts index c87005607de176170d8376bfa7b6949c5466cf52..e8a9bd01f19a18f12c5d764f65875acc2d185f42 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/api/queries/configApi.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/api/queries/configApi.ts @@ -9,6 +9,8 @@ import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; import { useConfigApi } from "@/lib/businessModules/schoolEntry/api/clients"; import { configApiQueryKey } from "@/lib/businessModules/schoolEntry/api/queries/apiQueryKeys"; +const CACHE_DURATION_1DAY = 86_400_000; + export function useGetLocationSelectionMode() { const configApi = useConfigApi(); const { data: locationSelectionMode } = useSuspenseQuery( @@ -22,5 +24,7 @@ export function getLocationSelectionModeQuery(configApi: SchoolEntryConfigApi) { queryKey: configApiQueryKey(["getConfig"]), queryFn: () => configApi.getConfig(), select: (response) => response.locationSelectionMode, + staleTime: CACHE_DURATION_1DAY, + gcTime: CACHE_DURATION_1DAY, }); } diff --git a/employee-portal/src/lib/businessModules/schoolEntry/api/queries/featureTogglesApi.ts b/employee-portal/src/lib/businessModules/schoolEntry/api/queries/featureTogglesApi.ts index 491a32d277d557e27ed3a0defba1514a871a54b6..1babf65213c46890061fd4682625f05a0f6496ba 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/api/queries/featureTogglesApi.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/api/queries/featureTogglesApi.ts @@ -8,10 +8,13 @@ import { ApiSchoolEntryFeature, } from "@eshg/employee-portal-api/schoolEntry"; import { + FeatureToggleQueryOptions, selectDisabledOldFeature, selectEnabledNewFeature, useGetFeatureToggle, + useGetFeatureToggleUnsuspended, } from "@eshg/lib-portal/api/featureToggles"; +import { UseQueryResult } from "@tanstack/react-query"; import { useFeatureTogglesApi } from "@/lib/businessModules/schoolEntry/api/clients"; import { schoolEntryFeatureTogglesApiQueryKey } from "@/lib/businessModules/schoolEntry/api/queries/apiQueryKeys"; @@ -20,6 +23,30 @@ export function useIsNewFeatureEnabled(name: ApiSchoolEntryFeature): boolean { return useGetSchoolEntryFeatureToggle(selectEnabledNewFeature(name)); } +export function useIsNewFeatureEnabledUnsuspended( + name: ApiSchoolEntryFeature, +): UseQueryResult<boolean> { + const enabledNewFeatureQuery = useEnabledNewFeatureToggleQuery(name); + return useGetFeatureToggleUnsuspended(enabledNewFeatureQuery); +} + +function useEnabledNewFeatureToggleQuery( + name: ApiSchoolEntryFeature, +): FeatureToggleQueryOptions<ApiSchoolEntryFeature, boolean> { + return useFeatureToggleQuery(selectEnabledNewFeature(name)); +} + +function useFeatureToggleQuery<TValue>( + select: (featureToggles: ApiGetSchoolEntryFeatureTogglesResponse) => TValue, +): FeatureToggleQueryOptions<ApiSchoolEntryFeature, TValue> { + const featureTogglesApi = useFeatureTogglesApi(); + return { + queryKey: schoolEntryFeatureTogglesApiQueryKey(["getFeatureToggles"]), + queryFn: () => featureTogglesApi.getFeatureToggles(), + select, + }; +} + export function useIsOldFeatureDisabled(name: ApiSchoolEntryFeature): boolean { return useGetSchoolEntryFeatureToggle(selectDisabledOldFeature(name)); } diff --git a/employee-portal/src/lib/businessModules/schoolEntry/api/queries/schoolEntryApi.ts b/employee-portal/src/lib/businessModules/schoolEntry/api/queries/schoolEntryApi.ts index 03858a7697ce06e77e14574cf34e34bdbc163f36..adf1eaa7495f7d8143ffb3e832f406c6e20fb55c 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/api/queries/schoolEntryApi.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/api/queries/schoolEntryApi.ts @@ -6,6 +6,7 @@ import { GetFreeAppointmentsForProcedureRequest, GetProceduresRequest, + GetWaitingRoomProceduresRequest, SchoolEntryApi, SearchIcd10CodesRequest, } from "@eshg/employee-portal-api/schoolEntry"; @@ -24,6 +25,7 @@ import { mapAppointment } from "@/lib/businessModules/schoolEntry/api/models/App import { mapProcedure } from "@/lib/businessModules/schoolEntry/api/models/Procedure"; import { mapProcedureDetails } from "@/lib/businessModules/schoolEntry/api/models/ProcedureDetails"; import { mapVaccinationStatus } from "@/lib/businessModules/schoolEntry/api/models/VaccinationStatus"; +import { mapWaitingRoomProcedure } from "@/lib/businessModules/schoolEntry/api/models/WaitingRoom"; import { mapDevelopmentScreeningResult } from "@/lib/businessModules/schoolEntry/api/models/examinations/DevelopmentScreeningResult"; import { mapEyeExaminationResult } from "@/lib/businessModules/schoolEntry/api/models/examinations/EyeExaminationResult"; import { mapHearingTestResult } from "@/lib/businessModules/schoolEntry/api/models/examinations/HearingTestResult"; @@ -159,3 +161,17 @@ export function getAnamnesisQuery( select: mapAnamnesis, }); } + +export function useGetWaitingRoomProcedures( + request: GetWaitingRoomProceduresRequest, +) { + const schoolEntryApi = useSchoolEntryApi(); + return useSuspenseQuery({ + queryKey: schoolEntryApiQueryKey(["getWaitingRoomProcedures", request]), + queryFn: () => + schoolEntryApi + .getWaitingRoomProceduresRaw(request) + .then(unwrapRawResponse), + select: mapPaginatedList(mapWaitingRoomProcedure), + }); +} diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/appointmentBlocks/appointmentBlocksGroupForm/AppointmentBlockGroupForm.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/appointmentBlocks/appointmentBlocksGroupForm/AppointmentBlockGroupForm.tsx index fade5dbcc4e0a8b506ca2240623d1faa5f5071ab..19c2346ef295a337202d2b6b03d04f4dcd17a147 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/appointmentBlocks/appointmentBlocksGroupForm/AppointmentBlockGroupForm.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/appointmentBlocks/appointmentBlocksGroupForm/AppointmentBlockGroupForm.tsx @@ -124,7 +124,7 @@ export function AppointmentBlockGroupForm( <Stack gap={4}> <AppointmentStaffSelection physicianOptions={physicianOptions} - medicalAssistantsOptions={medicalAssistantsOptions} + medicalAssistantOptions={medicalAssistantsOptions} freeStaff={props.freeStaff} blockedStaff={props.blockedStaff} validateAvailability={() => props.validateAvailability(values)} diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/AnamnesisForm.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/AnamnesisForm.tsx index a6e0b308723341ece94b43833106bdfcb61936e0..5478af262837d18a7a093ed7276f3a3bf5a6bfe2 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/AnamnesisForm.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/AnamnesisForm.tsx @@ -5,7 +5,10 @@ "use client"; -import { ApiSchoolEntryCountryCode } from "@eshg/employee-portal-api/schoolEntry"; +import { + ApiBooleanWithUnknown, + ApiSchoolEntryCountryCode, +} from "@eshg/employee-portal-api/schoolEntry"; import { SoftRequiredBooleanSelectField } from "@eshg/lib-portal/businessModules/schoolEntry/features/procedures/fieldVariants"; import { HorizontalField } from "@eshg/lib-portal/components/formFields/HorizontalField"; import { InputField } from "@eshg/lib-portal/components/formFields/InputField"; @@ -91,15 +94,15 @@ export interface DevelopmentInfoValues { } export interface CheckUpsValues { - u2: OptionalFieldValue<boolean>; - u3: OptionalFieldValue<boolean>; - u4: OptionalFieldValue<boolean>; - u5: OptionalFieldValue<boolean>; - u6: OptionalFieldValue<boolean>; - u7: OptionalFieldValue<boolean>; - u7a: OptionalFieldValue<boolean>; - u8: OptionalFieldValue<boolean>; - u9: OptionalFieldValue<boolean>; + u2: OptionalFieldValue<ApiBooleanWithUnknown>; + u3: OptionalFieldValue<ApiBooleanWithUnknown>; + u4: OptionalFieldValue<ApiBooleanWithUnknown>; + u5: OptionalFieldValue<ApiBooleanWithUnknown>; + u6: OptionalFieldValue<ApiBooleanWithUnknown>; + u7: OptionalFieldValue<ApiBooleanWithUnknown>; + u7a: OptionalFieldValue<ApiBooleanWithUnknown>; + u8: OptionalFieldValue<ApiBooleanWithUnknown>; + u9: OptionalFieldValue<ApiBooleanWithUnknown>; } export interface PromotionBeforeSchoolEntryValues { diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/CheckUpsForm.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/CheckUpsForm.tsx index c5e00cbfd0e29eaa5fcf491dd48391f30c85f417..720446344783c98df5110c5495ad15c7e44c022b 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/CheckUpsForm.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/CheckUpsForm.tsx @@ -5,8 +5,7 @@ "use client"; -import { SoftRequiredBooleanSelectField } from "@eshg/lib-portal/businessModules/schoolEntry/features/procedures/fieldVariants"; -import { HorizontalField } from "@eshg/lib-portal/components/formFields/HorizontalField"; +import { SoftRequiredSelectField } from "@eshg/lib-portal/businessModules/schoolEntry/features/procedures/fieldVariants"; import { createFieldNameMapper } from "@eshg/lib-portal/helpers/form"; import { NestedFormProps, @@ -16,8 +15,12 @@ import { import { Stack, Typography } from "@mui/joy"; import { CheckUpsValues } from "@/lib/businessModules/schoolEntry/features/procedures/anamnesis/AnamnesisForm"; -import { SetAllBooleanSelect } from "@/lib/businessModules/schoolEntry/features/procedures/examinations/SetAllSelect"; -import { BOOLEAN_SELECT_STYLE } from "@/lib/businessModules/schoolEntry/features/procedures/styles"; +import { SetAllBooleanWithUnknownSelect } from "@/lib/businessModules/schoolEntry/features/procedures/examinations/SetAllSelect"; +import { BOOLEAN_WITH_UNKNOWN_OPTIONS } from "@/lib/businessModules/schoolEntry/features/procedures/options"; +import { + BOOLEAN_SELECT_STYLE, + BOOLEAN_WITH_UNKNOWN_STYLE, +} from "@/lib/businessModules/schoolEntry/features/procedures/styles"; const CHECKUPS: { name: string; label: string }[] = [ { name: "u2", label: "U2" }, @@ -39,7 +42,7 @@ interface CheckUpsFormProps extends NestedFormProps { export function CheckUpsForm(props: CheckUpsFormProps) { const fieldName = createFieldNameMapper(props.name); - function setAllCheckUpFields(value: OptionalFieldValue<boolean>) { + function setAllCheckUpFields(value: OptionalFieldValue<string>) { CHECKUPS.forEach( (checkUp) => void props.setFieldValue(fieldName(checkUp.name), value), ); @@ -49,21 +52,20 @@ export function CheckUpsForm(props: CheckUpsFormProps) { <Stack gap={2} data-testid="checkUpsForm"> <Typography level="title-sm">Vorsorgeuntersuchungen</Typography> <Stack direction="row" gap={4}> - <SetAllBooleanSelect + <SetAllBooleanWithUnknownSelect label="Alle" onChange={setAllCheckUpFields} sx={BOOLEAN_SELECT_STYLE} /> <Stack direction="row" gap={4} flexWrap="wrap"> {CHECKUPS.map((checkUp) => ( - <SoftRequiredBooleanSelectField + <SoftRequiredSelectField key={checkUp.name} name={fieldName(checkUp.name)} label={checkUp.label} - component={HorizontalField} - sx={BOOLEAN_SELECT_STYLE} + options={BOOLEAN_WITH_UNKNOWN_OPTIONS} + sx={BOOLEAN_WITH_UNKNOWN_STYLE} softRequired - allowDeselection /> ))} </Stack> diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/MigrationBackgroundForm.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/MigrationBackgroundForm.tsx index bb1797f7d90d2be004fab0276bcbfeb401c34812..62361be5bbf0dfe8607bbf4c10c6abf77a6bf626 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/MigrationBackgroundForm.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/anamnesis/MigrationBackgroundForm.tsx @@ -187,7 +187,6 @@ export function MigrationBackgroundForm(props: MigrationBackgroundFormProps) { testId="inGermanySince" fieldName={fieldName("inGermanySince")} date={props.values.inGermanySince} - softRequired /> </Stack> </Stack> diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/developmentScreening/HandicapWithDiagnosisFields.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/developmentScreening/HandicapWithDiagnosisFields.tsx index 696a498adaa4f6cff9d7af57b1c00421d1848d2a..b10ba2abecc78f1dd971263c1bf6f4a76d3cc9a3 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/developmentScreening/HandicapWithDiagnosisFields.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/developmentScreening/HandicapWithDiagnosisFields.tsx @@ -62,6 +62,7 @@ export function HandicapWithDiagnosisFields( setFieldValue={props.setFieldValue} onClickIcd10Code={props.onClickIcd10Code} disabled={!props.values.result} + softRequired /> </Stack> ); diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/developmentScreening/PsychoSocialRiskFields.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/developmentScreening/PsychoSocialRiskFields.tsx index d3d9c2071553b5d845397e53d8910516975fb444..653c1f12e91f585891fecc131ffeae0dd71ce33d 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/developmentScreening/PsychoSocialRiskFields.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/developmentScreening/PsychoSocialRiskFields.tsx @@ -67,7 +67,6 @@ export function PsychoSocialRiskFields(props: PsychoSocialRiskFieldsProps) { label={field.label} sx={BOOLEAN_SELECT_STYLE} allowDeselection - softRequired /> ))} </Stack> diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/examinations/Icd10CodeField.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/examinations/Icd10CodeField.tsx index 37a441522213c6082897b2d19582182503c96dec..0175a09160118f7269fe5967b35960c796a5c98c 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/examinations/Icd10CodeField.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/examinations/Icd10CodeField.tsx @@ -9,7 +9,7 @@ import { HorizontalField } from "@eshg/lib-portal/components/formFields/Horizont import { InputField } from "@eshg/lib-portal/components/formFields/InputField"; import { FieldProps, SetFieldValueHelper } from "@eshg/lib-portal/types/form"; import { Search } from "@mui/icons-material"; -import { InputProps } from "@mui/joy"; +import { Input, InputProps } from "@mui/joy"; import { SxProps } from "@mui/joy/styles/types"; import { theme } from "@/lib/baseModule/theme/theme"; @@ -19,15 +19,6 @@ export type ClickIcd10CodeHandler = ( setFieldValue: (newCodes: string[]) => void, ) => void; -function Icd10CodeInput(props: InputProps) { - return ( - <SoftRequiredInput - {...props} - value={Array.isArray(props.value) ? props.value.join(", ") : props.value} - /> - ); -} - export const FIXED_WIDTH_STYLE: SxProps = { ".MuiInput-root": { width: "140px" }, }; @@ -37,11 +28,27 @@ interface Icd10CodeFieldProps extends Omit<FieldProps<string[]>, "label"> { disabled?: boolean; setFieldValue: SetFieldValueHelper; onClickIcd10Code: ClickIcd10CodeHandler; + softRequired?: boolean; } export function Icd10CodeField(props: Icd10CodeFieldProps) { const disabled = useIsFormDisabled(); + function Icd10CodeInput(inputProps: InputProps) { + const InputComponent = props.softRequired ? SoftRequiredInput : Input; + + return ( + <InputComponent + {...inputProps} + value={ + Array.isArray(inputProps.value) + ? inputProps.value.join(", ") + : inputProps.value + } + /> + ); + } + function handleClickIcd10Codes() { props.onClickIcd10Code(props.values, (newCodes) => { void props.setFieldValue(props.name, newCodes); diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/examinations/SetAllSelect.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/examinations/SetAllSelect.tsx index 1448b18e4bf93ee82e31779927fd59f01278a2a1..fa95a78396b6fb99e13bc0d6ef306254deb7bda0 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/examinations/SetAllSelect.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/examinations/SetAllSelect.tsx @@ -16,7 +16,10 @@ import { Option, Select } from "@mui/joy"; import { SxProps } from "@mui/joy/styles/types"; import { ReactNode } from "react"; -import { EXAMINATION_RESULT_OPTIONS } from "@/lib/businessModules/schoolEntry/features/procedures/options"; +import { + BOOLEAN_WITH_UNKNOWN_OPTIONS, + EXAMINATION_RESULT_OPTIONS, +} from "@/lib/businessModules/schoolEntry/features/procedures/options"; type SupportedTypes = string | boolean; @@ -59,6 +62,21 @@ export function SetAllBooleanSelect( ); } +export function SetAllBooleanWithUnknownSelect( + props: Omit<SetAllProps<string>, "children">, +) { + return ( + <SetAllSelect<string> + label={props.label} + sx={props.sx} + onChange={props.onChange} + orientation={props.orientation} + > + <SelectOptions options={BOOLEAN_WITH_UNKNOWN_OPTIONS} /> + </SetAllSelect> + ); +} + function SetAllSelect<TValue extends SupportedTypes>( props: SetAllProps<TValue>, ) { diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/options.ts b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/options.ts index d3f60c60b389a8cab1e1a9135744b1a7d4daf507..5d1a4e29f38f890dcc06ca4321aeb07da053f184 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/options.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/options.ts @@ -13,6 +13,7 @@ import { isDraft } from "@/lib/businessModules/schoolEntry/features/procedures/p import { APPOINTMENT_TYPES, ARTICULATION_VALUES, + BOOLEAN_WITH_UNKNOWN_VALUES, COUNTRY_CODE_VALUES, DISABILITY_TYPE_VALUES, DOCTOR_LETTER_VALUES, @@ -116,3 +117,8 @@ export const VACCINATION_SCHEME_OPTIONS = buildEnumOptions( ); export const WAITING_STATUS_OPTIONS = buildEnumOptions(WAITING_STATUS_VALUES); + +export const BOOLEAN_WITH_UNKNOWN_OPTIONS = buildEnumOptions( + BOOLEAN_WITH_UNKNOWN_VALUES, + true, +); diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ProcedureActionsPanel.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ProcedureActionsPanel.tsx index ae7fc649e3a5e3ff6eaa1b76003fc396e2f314b4..5040b1245fa2cdd87c12c00d2674821471f145c9 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ProcedureActionsPanel.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ProcedureActionsPanel.tsx @@ -10,6 +10,7 @@ import { ProcedureDetails } from "@/lib/businessModules/schoolEntry/api/models/P import { useIsNewFeatureEnabled } from "@/lib/businessModules/schoolEntry/api/queries/featureTogglesApi"; import { CloseProcedureModal } from "@/lib/businessModules/schoolEntry/features/procedures/procedureDetails/CloseProcedureModal"; import { DeleteProcedureModal } from "@/lib/businessModules/schoolEntry/features/procedures/procedureDetails/DeleteProcedureModal"; +import { ReopenProcedureModal } from "@/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ReopenProcedureModal"; import { OpenModalButton } from "@/lib/shared/components/buttons/OpenModalButton"; import { ContentPanel } from "@/lib/shared/components/contentPanel/ContentPanel"; @@ -20,6 +21,9 @@ export function ProcedureActionsPanel(props: { procedure: ProcedureDetails }) { const deleteProcedureEnabled = useIsNewFeatureEnabled( ApiSchoolEntryFeature.DeleteProcedure, ); + const reopenProcedureEnabled = useIsNewFeatureEnabled( + ApiSchoolEntryFeature.ReopenProcedure, + ); const buttons: ReactNode[] = []; @@ -36,6 +40,20 @@ export function ProcedureActionsPanel(props: { procedure: ProcedureDetails }) { ); } + if (reopenProcedureEnabled && props.procedure.isClosed) { + buttons.push( + <OpenModalButton + key="reopenProcedure" + renderModal={(modalProps) => ( + <ReopenProcedureModal procedure={props.procedure} {...modalProps} /> + )} + color="danger" + > + Vorgang wiedereröffnen + </OpenModalButton>, + ); + } + if (deleteProcedureEnabled && props.procedure.isDeletable) { buttons.push( <OpenModalButton diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ProcedureDetails.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ProcedureDetails.tsx index 69a94bab430bd82d7c9b3e4a3d6dade25663d40c..aca216b6e6c17760bb1b57ac458d22b2911f03b3 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ProcedureDetails.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ProcedureDetails.tsx @@ -5,7 +5,10 @@ "use client"; -import { ApiSchoolEntryFeature } from "@eshg/employee-portal-api/schoolEntry"; +import { + ApiLocationSelectionMode, + ApiSchoolEntryFeature, +} from "@eshg/employee-portal-api/schoolEntry"; import { Grid, Stack } from "@mui/joy"; import { isDefined } from "remeda"; @@ -23,13 +26,16 @@ const SPACING = { xxs: 2, sm: 3, md: 4, xxl: 5 }; interface ProcedureDetailsProps { procedure: ProcedureDetailsType; + locationSelectionMode: ApiLocationSelectionMode; } -export function ProcedureDetails({ procedure }: ProcedureDetailsProps) { +export function ProcedureDetails(props: ProcedureDetailsProps) { const waitingRoomEnabled = useIsNewFeatureEnabled( ApiSchoolEntryFeature.WaitingRoom, ); + const procedure = props.procedure; + return ( <PageGrid> <Grid xs={8}> @@ -58,6 +64,7 @@ export function ProcedureDetails({ procedure }: ProcedureDetailsProps) { <ProcedureDetailsSection procedure={procedure} /> <ProcedureActionsPanel procedure={procedure} /> {waitingRoomEnabled && + props.locationSelectionMode === ApiLocationSelectionMode.None && !procedure.isClosed && isDefined(procedure.appointment) && ( <WaitingRoomPanel procedure={procedure} /> diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ReopenProcedureModal.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ReopenProcedureModal.tsx new file mode 100644 index 0000000000000000000000000000000000000000..85b57f99418d60695ecbb53d0675aa40a1f01c47 --- /dev/null +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/procedureDetails/ReopenProcedureModal.tsx @@ -0,0 +1,59 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { formatDate } from "@eshg/lib-portal/formatters/dateTime"; +import { formatPersonName } from "@eshg/lib-portal/formatters/person"; +import { Button, Stack, Typography } from "@mui/joy"; + +import { ProcedureDetails } from "@/lib/businessModules/schoolEntry/api/models/ProcedureDetails"; +import { useReopenProcedure } from "@/lib/businessModules/schoolEntry/api/mutations/schoolEntryApi"; +import { BaseModal, BaseModalProps } from "@/lib/shared/components/BaseModal"; +import { DataField } from "@/lib/shared/components/modal/DataField"; + +interface ReopenProcedureModalProps extends Omit<BaseModalProps, "children"> { + procedure: ProcedureDetails; +} + +export function ReopenProcedureModal(props: ReopenProcedureModalProps) { + const reopenProcedure = useReopenProcedure(); + async function handleSubmit() { + await reopenProcedure + .mutateAsync({ + procedureId: props.procedure.id, + apiReopenProcedureRequest: { + version: props.procedure.version, + }, + }) + .catch(); + props.onClose(); + } + + return ( + <BaseModal modalTitle="Vorgang wiedereröffnen?" {...props}> + <Typography level="body-md" marginBottom={1}> + Durch das Wiedereröffnen können bestehende Daten geändert werden. + </Typography> + <DataField label="Name" value={formatPersonName(props.procedure.child)} /> + <DataField + label="Geburtsdatum" + value={formatDate(props.procedure.child.dateOfBirth)} + /> + <Stack + direction="row" + gap={2} + alignItems="center" + justifyContent="flex-end" + > + <Button variant="outlined" color="neutral" onClick={props.onClose}> + Abbrechen + </Button> + + <Button color="danger" onClick={handleSubmit}> + Wiedereröffnen + </Button> + </Stack> + </BaseModal> + ); +} diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/proceduresTable/ProcedureFilterSettings.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/proceduresTable/ProcedureFilterSettings.tsx index 448bcef8b3c1ef1beb46af792d8e957c2007d20e..b9a9b924b1e4f35feecdc58d5207a424bf55d320 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/proceduresTable/ProcedureFilterSettings.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/proceduresTable/ProcedureFilterSettings.tsx @@ -36,6 +36,7 @@ export type ProcedureFilters = Pick< | "dayOfAppointmentFilter" | "hasAppointmentFilter" | "schoolYearFilter" + | "labelsFilter" >; const FILTER_NAMES: Record<keyof ProcedureFilters, string> = { @@ -44,6 +45,7 @@ const FILTER_NAMES: Record<keyof ProcedureFilters, string> = { dayOfAppointmentFilter: "Untersuchung am", hasAppointmentFilter: "Termin", schoolYearFilter: "Schuljahr", + labelsFilter: "Kennungen", }; function getFilterLabel(filterValue: ActiveFilter<keyof ProcedureFilters>) { diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/styles.ts b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/styles.ts index 42d9d161fd31d493d80b3959a7850e38a31b9d44..d032513590aa3111c7eefe4d92f8b645ea7a5987 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/styles.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/styles.ts @@ -20,3 +20,7 @@ export const BOLD_LABEL_STYLE = { fontWeight: "bold", }, }; + +export const BOOLEAN_WITH_UNKNOWN_STYLE: SxProps = { + ".MuiSelect-root": { width: "145px" }, +}; diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/translations.ts b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/translations.ts index 51422f577754d17f6ded011f7514a3b8f233e369..2b5c33161ae4579f80c6b2faf701fc1913963560 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/translations.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/translations.ts @@ -6,6 +6,7 @@ import { ApiAppointmentType, ApiArticulationValue, + ApiBooleanWithUnknown, ApiDisabilityType, ApiDoctorLetterValue, ApiEvaluationArticulationValue, @@ -450,3 +451,9 @@ export const REQUIRED_PROCEDURE_DATA: EnumMap<ApiRequiredProcedureData> = { [ApiRequiredProcedureData.DevelopmentScreening]: "S1 - Befund", [ApiRequiredProcedureData.VaccinationStatus]: "Impfstatus", }; + +export const BOOLEAN_WITH_UNKNOWN_VALUES: EnumMap<ApiBooleanWithUnknown> = { + [ApiBooleanWithUnknown.True]: "Ja", + [ApiBooleanWithUnknown.False]: "Nein", + [ApiBooleanWithUnknown.Unknown]: "Unbekannt", +}; diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/vaccination/VaccinationForm.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/vaccination/VaccinationForm.tsx index ce1def5320e6c7a44cd50fce9d9c0cfbfbfed39a..0122a0f87d5c9e79d8de44c65b2299b0fc6af782 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/vaccination/VaccinationForm.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/procedures/vaccination/VaccinationForm.tsx @@ -5,7 +5,10 @@ "use client"; -import { ApiVaccinationSchemeValue } from "@eshg/employee-portal-api/schoolEntry"; +import { + ApiBooleanWithUnknown, + ApiVaccinationSchemeValue, +} from "@eshg/employee-portal-api/schoolEntry"; import { SoftRequiredBooleanSelectField, SoftRequiredSelectField, @@ -27,8 +30,14 @@ import { FieldArray, Formik, FormikHelpers } from "formik"; import { FormFooter } from "@/lib/businessModules/schoolEntry/features/procedures/examinations/FormFooter"; import { SetAllNumberInput } from "@/lib/businessModules/schoolEntry/features/procedures/examinations/SetAllNumberInput"; -import { VACCINATION_SCHEME_OPTIONS } from "@/lib/businessModules/schoolEntry/features/procedures/options"; -import { BOOLEAN_SELECT_STYLE } from "@/lib/businessModules/schoolEntry/features/procedures/styles"; +import { + BOOLEAN_WITH_UNKNOWN_OPTIONS, + VACCINATION_SCHEME_OPTIONS, +} from "@/lib/businessModules/schoolEntry/features/procedures/options"; +import { + BOOLEAN_SELECT_STYLE, + BOOLEAN_WITH_UNKNOWN_STYLE, +} from "@/lib/businessModules/schoolEntry/features/procedures/styles"; import { OtherVaccinationForm } from "@/lib/businessModules/schoolEntry/features/procedures/vaccination/OtherVaccinationForm"; import { VACCINATION_FIELD_STYLE, @@ -62,7 +71,7 @@ export interface VaccinationFormValues { hepatitisA: OptionalFieldValue<number>; otherVaccinations: OtherVaccinationValues[]; vaccinationPassPresented: OptionalFieldValue<boolean>; - perkombiHbv: OptionalFieldValue<boolean>; + perkombiHbv: OptionalFieldValue<ApiBooleanWithUnknown>; } export interface OtherVaccinationValues { @@ -206,11 +215,12 @@ export function VaccinationForm(props: FormProps<VaccinationFormValues>) { )} </FieldArray> </Stack> - <SoftRequiredBooleanSelectField + <SoftRequiredSelectField name="perkombiHbv" label="PerkombiHBV" - allowDeselection - sx={BOOLEAN_SELECT_STYLE} + options={BOOLEAN_WITH_UNKNOWN_OPTIONS} + sx={BOOLEAN_WITH_UNKNOWN_STYLE} + softRequired /> <Divider /> <SoftRequiredBooleanSelectField diff --git a/employee-portal/src/lib/businessModules/schoolEntry/features/waitingRoom/WaitingRoomTable.tsx b/employee-portal/src/lib/businessModules/schoolEntry/features/waitingRoom/WaitingRoomTable.tsx new file mode 100644 index 0000000000000000000000000000000000000000..616cc8a5a08e27438e5d2dbfebabb85bfc8ceeef --- /dev/null +++ b/employee-portal/src/lib/businessModules/schoolEntry/features/waitingRoom/WaitingRoomTable.tsx @@ -0,0 +1,168 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiWaitingRoomSortKey } from "@eshg/employee-portal-api/schoolEntry"; +import { + formatDate, + formatDateTime, +} from "@eshg/lib-portal/formatters/dateTime"; +import { ColumnSort, createColumnHelper } from "@tanstack/react-table"; +import { isDefined, isNullish } from "remeda"; + +import { WaitingRoomProcedure } from "@/lib/businessModules/schoolEntry/api/models/WaitingRoom"; +import { useGetWaitingRoomProcedures } from "@/lib/businessModules/schoolEntry/api/queries/schoolEntryApi"; +import { WAITING_STATUS_VALUES } from "@/lib/businessModules/schoolEntry/features/procedures/translations"; +import { routes } from "@/lib/businessModules/schoolEntry/shared/routes"; +import { Pagination } from "@/lib/shared/components/pagination/Pagination"; +import { DataTable } from "@/lib/shared/components/table/DataTable"; +import { TablePage } from "@/lib/shared/components/table/TablePage"; +import { TableSheet } from "@/lib/shared/components/table/TableSheet"; +import { getSortDirection } from "@/lib/shared/components/table/sorting"; +import { + CustomSortingProps, + useTableControl, +} from "@/lib/shared/hooks/searchParams/useTableControl"; + +const initialSorting: ColumnSort = { + id: "modifiedAt", + desc: true, +}; + +export function WaitingRoomTable() { + const tableControl = useTableControl({ + serverSideSorting: true, + sortFieldName: "sortKey", + sortDirectionName: "sortDirection", + initialSorting: initialSorting, + }); + + const procedures = useGetWaitingRoomProcedures({ + pageNumber: tableControl.paginationProps.pageNumber, + pageSize: tableControl.paginationProps.pageSize, + sortKey: getSortKey(tableControl.tableSorting), + sortDirection: getSortDirection(tableControl.tableSorting), + }); + + return ( + <TablePage fullHeight> + <TableSheet + loading={procedures.isFetching} + footer={ + <Pagination + totalCount={procedures.data.totalNumberOfElements} + {...tableControl.paginationProps} + /> + } + > + <DataTable + data={procedures.data.elements} + columns={COLUMNS} + sorting={tableControl.tableSorting} + enableSortingRemoval={false} + rowNavRoute={(row) => routes.procedures.byId(row.original.id).details} + minWidth={1200} + /> + </TableSheet> + </TablePage> + ); +} + +const columnHelper = createColumnHelper<WaitingRoomProcedure>(); +const COLUMNS = [ + columnHelper.accessor("child.lastName", { + header: "Name", + cell: (props) => props.getValue(), + enableSorting: true, + meta: { + canNavigate: { + parentRow: true, + }, + width: 180, + }, + }), + columnHelper.accessor("child.firstName", { + header: "Vorname", + cell: (props) => props.getValue(), + enableSorting: true, + meta: { + canNavigate: { + parentRow: true, + }, + width: 180, + }, + }), + columnHelper.accessor("child.dateOfBirth", { + header: "Geburtsdatum", + cell: (props) => formatDate(props.getValue()), + enableSorting: true, + meta: { + canNavigate: { + parentRow: true, + }, + width: 155, + }, + }), + columnHelper.accessor("waitingRoom.description", { + header: "Info", + cell: (props) => props.getValue(), + enableSorting: true, + meta: { + canNavigate: { + parentRow: true, + }, + width: 245, + }, + }), + columnHelper.accessor("waitingRoom.status", { + header: "Status", + cell: (props) => + isDefined(props.getValue()) + ? WAITING_STATUS_VALUES[props.getValue()!] + : undefined, + enableSorting: true, + meta: { + canNavigate: { + parentRow: true, + }, + width: 220, + }, + }), + columnHelper.accessor("modifiedAt", { + header: "Seit", + cell: (props) => + isNullish(props.getValue()) + ? "" + : `${formatDateTime(props.getValue())} Uhr`, + enableSorting: true, + meta: { + canNavigate: { + parentRow: true, + }, + }, + }), +]; + +const SORT_KEY_MAPPING: Record<string, ApiWaitingRoomSortKey> = { + child_firstName: ApiWaitingRoomSortKey.Firstname, + child_lastName: ApiWaitingRoomSortKey.Lastname, + child_dateOfBirth: ApiWaitingRoomSortKey.DateOfBirth, + waitingRoom_info: ApiWaitingRoomSortKey.Info, + waitingRoom_status: ApiWaitingRoomSortKey.Status, + waitingRoom_modifiedAt: ApiWaitingRoomSortKey.ModifiedAt, +}; + +function getSortKey( + sortingProps: CustomSortingProps, +): ApiWaitingRoomSortKey | undefined { + const sorting = sortingProps.manualSorting + ? sortingProps.sortingState + : sortingProps.initialSorting; + if (sorting?.[0] === undefined) return undefined; + + const columnId = sorting[0].id; + return SORT_KEY_MAPPING[columnId]; +} diff --git a/employee-portal/src/lib/businessModules/schoolEntry/shared/routes.ts b/employee-portal/src/lib/businessModules/schoolEntry/shared/routes.ts index b8d27e13fefbdc2a4238b2a56c1777bdea34cd44..370571b834eeb4dce95e194d8cc09c97b1562d81 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/shared/routes.ts +++ b/employee-portal/src/lib/businessModules/schoolEntry/shared/routes.ts @@ -46,6 +46,7 @@ export const routes = defineRoutes("/school-entry", (schoolEntryPath) => ({ })), }), ), + waitingRoom: schoolEntryPath("/waiting-room"), appointmentBlockGroups: defineRoutes( schoolEntryPath("/appointment-block-groups"), (appointmentBlockGroupsPath) => ({ diff --git a/employee-portal/src/lib/businessModules/schoolEntry/shared/sideNavigationItem.tsx b/employee-portal/src/lib/businessModules/schoolEntry/shared/sideNavigationItem.tsx index 49c93307abb5f4a4a8ea2715a094ab7ac42e385e..b4abeccd946e882307a8f8e37952295c2801b23d 100644 --- a/employee-portal/src/lib/businessModules/schoolEntry/shared/sideNavigationItem.tsx +++ b/employee-portal/src/lib/businessModules/schoolEntry/shared/sideNavigationItem.tsx @@ -4,28 +4,38 @@ */ import { ApiBaseFeature, ApiUserRole } from "@eshg/employee-portal-api/base"; +import { + ApiLocationSelectionMode, + ApiSchoolEntryFeature, +} from "@eshg/employee-portal-api/schoolEntry"; import { EscalatorWarning } from "@mui/icons-material"; +import { useQuery } from "@tanstack/react-query"; import { useIsNewFeatureEnabled } from "@/lib/baseModule/api/queries/feature"; import { SideNavigationItem, SideNavigationSubItem, } from "@/lib/baseModule/components/layout/sideNavigation/types"; +import { useConfigApi } from "@/lib/businessModules/schoolEntry/api/clients"; +import { getLocationSelectionModeQuery } from "@/lib/businessModules/schoolEntry/api/queries/configApi"; +import { useIsNewFeatureEnabledUnsuspended } from "@/lib/businessModules/schoolEntry/api/queries/featureTogglesApi"; import { hasUserRole } from "@/lib/shared/helpers/accessControl"; import { routes } from "./routes"; -const sideNavigationItem = { - name: "Einschulung", - decorator: <EscalatorWarning />, +const waitingRoomNavigationItem: SideNavigationSubItem = { + name: "Wartezimmer", + href: routes.waitingRoom, + accessCheck: hasUserRole(ApiUserRole.SchoolEntryAdmin), +}; + +const proceduresNavigationItem: SideNavigationSubItem = { + name: "Vorgänge", + href: routes.procedures.overview, + accessCheck: hasUserRole(ApiUserRole.SchoolEntryAdmin), }; const defaultSubItems: SideNavigationSubItem[] = [ - { - name: "Vorgänge", - href: routes.procedures.overview, - accessCheck: hasUserRole(ApiUserRole.SchoolEntryAdmin), - }, { name: "Terminblöcke", href: routes.appointmentBlockGroups.overview, @@ -46,8 +56,37 @@ const inboxNavigationItem: SideNavigationSubItem = { export function useSideNavigationItems(): SideNavigationItem[] { const isInboxEnabled = useIsNewFeatureEnabled(ApiBaseFeature.Inbox); - const subItems = isInboxEnabled - ? [...defaultSubItems, inboxNavigationItem] - : defaultSubItems; + + const { data: isWaitingRoomEnabled, isError: isWaitingRoomError } = + useIsNewFeatureEnabledUnsuspended(ApiSchoolEntryFeature.WaitingRoom); + + const configApi = useConfigApi(); + const { data: locationSelectionMode, isError: isLocationModeError } = + useQuery({ + ...getLocationSelectionModeQuery(configApi), + throwOnError: false, + }); + + const hasLocationMode = + locationSelectionMode !== ApiLocationSelectionMode.None; + + const subItems = [ + proceduresNavigationItem, + ...(isWaitingRoomEnabled && !hasLocationMode + ? [waitingRoomNavigationItem] + : []), + ...defaultSubItems, + ...(isInboxEnabled ? [inboxNavigationItem] : []), + ]; + + const sideNavigationItem = { + name: "Einschulung", + decorator: <EscalatorWarning />, + error: + isWaitingRoomError || isLocationModeError + ? "Bei der Verbindung zum Einschulungsmodul ist ein Fehler aufgetreten." + : undefined, + }; + return [{ ...sideNavigationItem, subItems }]; } diff --git a/employee-portal/src/lib/businessModules/statistics/api/mutations/useAddGeoShape.ts b/employee-portal/src/lib/businessModules/statistics/api/mutations/useAddGeoShape.ts index b8d3ad2220d542dd10115547836391b11b26e830..467129a8af2677dfc3ad343d7cc97d0c0ea8b7f9 100644 --- a/employee-portal/src/lib/businessModules/statistics/api/mutations/useAddGeoShape.ts +++ b/employee-portal/src/lib/businessModules/statistics/api/mutations/useAddGeoShape.ts @@ -8,7 +8,7 @@ import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvid import { mapRequiredValue } from "@eshg/lib-portal/helpers/form"; import { useGeoShapeApi } from "@/lib/businessModules/statistics/api/clients"; -import { AddGeoShapeValues } from "@/lib/businessModules/statistics/components/geoshapes/ImportGeoShapesSidebar"; +import { AddGeoShapeValues } from "@/lib/businessModules/statistics/components/geoshapes/ImportGeoShapeSidebar/ImportGeoShapeSidebar"; export function useAddGeoShape() { const snackbar = useSnackbar(); diff --git a/employee-portal/src/lib/businessModules/statistics/api/mutations/useDeleteReport.ts b/employee-portal/src/lib/businessModules/statistics/api/mutations/useDeleteReport.ts index 90bc3a8fc921383c7a3b26dd6d97b51dc3d36827..bb3b2ac4c1c737beba49f62229825bfc2d4aaabb 100644 --- a/employee-portal/src/lib/businessModules/statistics/api/mutations/useDeleteReport.ts +++ b/employee-portal/src/lib/businessModules/statistics/api/mutations/useDeleteReport.ts @@ -8,7 +8,9 @@ import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvid import { useReportSeriesApi } from "@/lib/businessModules/statistics/api/clients"; -export function useDeleteReport() { +export function useDeleteReport({ + onSuccess, +}: { onSuccess?: () => void } = {}) { const snackbar = useSnackbar(); const api = useReportSeriesApi(); const mutation = useHandledMutation({ @@ -17,6 +19,6 @@ export function useDeleteReport() { }); return (reportId: string) => { - return mutation.mutate(reportId); + return mutation.mutate(reportId, { onSuccess }); }; } diff --git a/employee-portal/src/lib/businessModules/statistics/api/mutations/useEditStatisticName.ts b/employee-portal/src/lib/businessModules/statistics/api/mutations/useEditStatisticName.ts new file mode 100644 index 0000000000000000000000000000000000000000..5859d8de54e540d47749349ae375fe60126d6c81 --- /dev/null +++ b/employee-portal/src/lib/businessModules/statistics/api/mutations/useEditStatisticName.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useHandledMutation } from "@eshg/lib-portal/api/useHandledMutation"; +import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; + +export function useEditStatisticName() { + // TODO: Implement, once the API has been defined + const snackbar = useSnackbar(); + const mutation = useHandledMutation({ + mutationFn: () => Promise.resolve(), + onSuccess: () => snackbar.confirmation("Name geändert."), + }); + return async (_name: string) => { + return mutation.mutateAsync().catch(); + }; +} diff --git a/employee-portal/src/lib/businessModules/statistics/api/mutations/useGeoShapeApi.ts b/employee-portal/src/lib/businessModules/statistics/api/mutations/useGeoShapeApi.ts index bc4f6bf71c9107fd6c1cefc87b2ce013549c5097..d363d8a0916a0004263de18124ec3de2fb2c4ab9 100644 --- a/employee-portal/src/lib/businessModules/statistics/api/mutations/useGeoShapeApi.ts +++ b/employee-portal/src/lib/businessModules/statistics/api/mutations/useGeoShapeApi.ts @@ -7,7 +7,7 @@ import { useHandledMutation } from "@eshg/lib-portal/api/useHandledMutation"; import { mapRequiredValue } from "@eshg/lib-portal/helpers/form"; import { useGeoShapeApi } from "@/lib/businessModules/statistics/api/clients"; -import { AddGeoShapeValues } from "@/lib/businessModules/statistics/components/geoshapes/ImportGeoShapesSidebar"; +import { AddGeoShapeValues } from "@/lib/businessModules/statistics/components/geoshapes/ImportGeoShapeSidebar/ImportGeoShapeSidebar"; export function useAddGeoShape() { const geoShapeApi = useGeoShapeApi(); diff --git a/employee-portal/src/lib/businessModules/statistics/components/geoshapes/GeoShapesOverview.tsx b/employee-portal/src/lib/businessModules/statistics/components/geoshapes/GeoShapesOverview.tsx index bc3530b3424741d5470a6c346d3ab691ef0b45f9..3bcf42b4e0eae115e4e24da1c491c9c9d8e74988 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/geoshapes/GeoShapesOverview.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/geoshapes/GeoShapesOverview.tsx @@ -7,7 +7,7 @@ import { useState } from "react"; -import { ImportGeoShapeSidebar } from "@/lib/businessModules/statistics/components/geoshapes/ImportGeoShapesSidebar"; +import { ImportGeoShapeSidebar } from "@/lib/businessModules/statistics/components/geoshapes/ImportGeoShapeSidebar/ImportGeoShapeSidebar"; import { OverlayBoundary } from "@/lib/shared/components/boundaries/OverlayBoundary"; import { GeoShapesTable } from "./GeoShapesTable"; diff --git a/employee-portal/src/lib/businessModules/statistics/components/geoshapes/ImportGeoShapeSidebar/ImportGeoShapeSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/geoshapes/ImportGeoShapeSidebar/ImportGeoShapeSidebar.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a82ffd597f790bb28ecf22b1257f275655c11835 --- /dev/null +++ b/employee-portal/src/lib/businessModules/statistics/components/geoshapes/ImportGeoShapeSidebar/ImportGeoShapeSidebar.tsx @@ -0,0 +1,49 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useAddGeoShape } from "@/lib/businessModules/statistics/api/mutations/useAddGeoShape"; +import { ImportGeoShapeStep } from "@/lib/businessModules/statistics/components/geoshapes/ImportGeoShapeSidebar/ImportGeoShapeStep"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; + +export interface AddGeoShapeValues { + file: File | null; + title: string; +} + +export function ImportGeoShapeSidebar(props: { + open: boolean; + onClose: () => void; +}) { + const initialValues: AddGeoShapeValues = { + file: null, + title: "", + }; + + const addGeoShape = useAddGeoShape(); + + async function handleSubmit(values: AddGeoShapeValues) { + await addGeoShape(values, { + onSuccess: props.onClose, + }); + } + + return ( + <SidebarStepper + onClose={props.onClose} + open={props.open} + onSubmit={handleSubmit} + initialValues={initialValues} + steps={[ + { + type: "StandardStep", + step: { + title: "Daten importieren", + content: <ImportGeoShapeStep />, + }, + }, + ]} + /> + ); +} diff --git a/employee-portal/src/lib/businessModules/statistics/components/geoshapes/ImportGeoShapeSidebar/ImportGeoShapeStep.tsx b/employee-portal/src/lib/businessModules/statistics/components/geoshapes/ImportGeoShapeSidebar/ImportGeoShapeStep.tsx new file mode 100644 index 0000000000000000000000000000000000000000..09f0e2bb6dae5a21bb306a0d1dacfbab84bec47b --- /dev/null +++ b/employee-portal/src/lib/businessModules/statistics/components/geoshapes/ImportGeoShapeSidebar/ImportGeoShapeStep.tsx @@ -0,0 +1,32 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { InputField } from "@eshg/lib-portal/components/formFields/InputField"; +import { Stack } from "@mui/joy"; + +import { DeletableFileField } from "@/lib/shared/components/formFields/file/DeletableFileField"; +import { FileType } from "@/lib/shared/components/formFields/file/FileType"; + +export function ImportGeoShapeStep() { + return ( + <> + <Stack gap={3}> + <DeletableFileField + name="file" + label="Karten-Datei für den Import auswählen:" + required="Bitte Shapefile importieren." + accept={FileType.Geojson} + placeholder=".geojson" + /> + <InputField + name="title" + label="Name für Choroplethenkarte" + required="Bitte Namen angeben." + hint="Der Name wird in der Kartenauswahl angezeigt." + /> + </Stack> + </> + ); +} diff --git a/employee-portal/src/lib/businessModules/statistics/components/geoshapes/ImportGeoShapesSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/geoshapes/ImportGeoShapesSidebar.tsx deleted file mode 100644 index f26ac059b7c4c1ee07ddfaa2cd7db12e15c3f25b..0000000000000000000000000000000000000000 --- a/employee-portal/src/lib/businessModules/statistics/components/geoshapes/ImportGeoShapesSidebar.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { InputField } from "@eshg/lib-portal/components/formFields/InputField"; -import { Button, Stack } from "@mui/joy"; -import { Formik } from "formik"; - -import { useAddGeoShape } from "@/lib/businessModules/statistics/api/mutations/useAddGeoShape"; -import { FormButtonBar } from "@/lib/shared/components/form/FormButtonBar"; -import { SidebarForm } from "@/lib/shared/components/form/SidebarForm"; -import { DeletableFileField } from "@/lib/shared/components/formFields/file/DeletableFileField"; -import { FileType } from "@/lib/shared/components/formFields/file/FileType"; -import { Sidebar } from "@/lib/shared/components/sidebar/Sidebar"; -import { SidebarActions } from "@/lib/shared/components/sidebar/SidebarActions"; -import { SidebarContent } from "@/lib/shared/components/sidebar/SidebarContent"; - -export interface AddGeoShapeValues { - file: File | null; - title: string; -} - -export function ImportGeoShapeSidebar(props: { - open: boolean; - onClose: () => void; -}) { - const initialValues: AddGeoShapeValues = { - file: null, - title: "", - }; - - const addGeoShape = useAddGeoShape(); - - async function handleSubmit(values: AddGeoShapeValues) { - await addGeoShape(values, { - onSuccess: props.onClose, - }); - } - - return ( - <Sidebar open={props.open} onClose={props.onClose}> - {props.open && ( - <Formik initialValues={initialValues} onSubmit={handleSubmit}> - {({ isSubmitting, handleSubmit }) => ( - <SidebarForm onSubmit={handleSubmit}> - <SidebarContent title="Daten importieren"> - <Stack gap={3}> - <DeletableFileField - name="file" - label="Karten-Datei für den Import auswählen:" - required="Bitte Shapefile importieren." - accept={FileType.Geojson} - placeholder=".geojson" - /> - <InputField - name="title" - label="Name für Choroplethenkarte" - required="Bitte Namen angeben." - hint="Der Name wird in der Kartenauswahl angezeigt." - /> - </Stack> - </SidebarContent> - <SidebarActions> - <FormButtonBar - left={ - <Button variant="plain" onClick={props.onClose}> - Abbrechen - </Button> - } - submitLabel="Speichern" - submitting={isSubmitting} - /> - </SidebarActions> - </SidebarForm> - )} - </Formik> - )} - </Sidebar> - ); -} diff --git a/employee-portal/src/lib/businessModules/statistics/components/reports/ReportDetailsTile.tsx b/employee-portal/src/lib/businessModules/statistics/components/reports/ReportDetailsTile.tsx index 29658627267505e7e7c1b86c3ab995b2cd75deed..2a18ef3e938368372c134fc157de985e5eb04e01 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/reports/ReportDetailsTile.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/reports/ReportDetailsTile.tsx @@ -49,11 +49,7 @@ function getActionItems( seriesId: string, description: string | undefined, updateReport: (report: UpdateReportSidebarReportInfo) => void, - deleteReportWithConfirmation: ( - reportId: string, - name: string, - redirectRoute: string, - ) => void, + deleteReportWithConfirmation: (reportId: string, name: string) => void, ) { // Uncomment in https://cronn-gmbh.atlassian.net/browse/ISSUE-5001 // const rememberReport = { @@ -85,8 +81,7 @@ function getActionItems( }, { label: "Report löschen", - onClick: () => - deleteReportWithConfirmation(seriesId, name, routes.reports.index), + onClick: () => deleteReportWithConfirmation(seriesId, name), startDecorator: <Delete />, color: "danger", }, @@ -103,7 +98,9 @@ function getActionItems( export function ReportDetailsTile(props: ReportDetailsTileProps) { const [openUpdateReportSidebar, setOpenUpdateReportSidebar] = useState<UpdateReportSidebarReportInfo | null>(null); - const deleteReportWithConfirmation = useDeleteReportWithConfirmation(); + const deleteReportWithConfirmation = useDeleteReportWithConfirmation({ + redirectRoute: routes.reports.index, + }); function updateReport(report: UpdateReportSidebarReportInfo) { setOpenUpdateReportSidebar({ ...report }); diff --git a/employee-portal/src/lib/businessModules/statistics/components/reports/useDeleteReportWithConfirmation.ts b/employee-portal/src/lib/businessModules/statistics/components/reports/useDeleteReportWithConfirmation.ts index e664acf6c918aba3409d6d390a06be74c34ddd11..0485d4998799d8b64315a389c7ccc69382baf8c3 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/reports/useDeleteReportWithConfirmation.ts +++ b/employee-portal/src/lib/businessModules/statistics/components/reports/useDeleteReportWithConfirmation.ts @@ -9,16 +9,22 @@ import { isDefined } from "remeda"; import { useDeleteReport } from "@/lib/businessModules/statistics/api/mutations/useDeleteReport"; import { useConfirmationDialog } from "@/lib/shared/components/confirmationDialog/ConfirmationDialogProvider"; -export function useDeleteReportWithConfirmation() { +export function useDeleteReportWithConfirmation({ + redirectRoute, +}: { + redirectRoute?: string; +} = {}) { const { openConfirmationDialog } = useConfirmationDialog(); - const deleteReport = useDeleteReport(); const router = useRouter(); + const deleteReport = useDeleteReport({ + onSuccess: () => { + if (isDefined(redirectRoute)) { + router.push(redirectRoute); + } + }, + }); - function deleteReportWithConfirmation( - seriesId: string, - reportName: string, - redirectRoute?: string, - ) { + function deleteReportWithConfirmation(seriesId: string, reportName: string) { openConfirmationDialog({ title: "Report löschen?", description: `Der Report "${reportName}" wird dann unwiderruflich gelöscht.`, @@ -26,9 +32,6 @@ export function useDeleteReportWithConfirmation() { color: "danger", onConfirm: () => { deleteReport(seriesId); - if (isDefined(redirectRoute)) { - router.push(redirectRoute); - } }, }); } diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/CreateStatisticFromScratchSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/CreateStatisticFromScratchSidebar.tsx index 73e79ed918a3fb4b07b57280085a772172830f8a..571e1ea07fd4380240610bed1e93e1bd2416e943 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/CreateStatisticFromScratchSidebar.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/CreateStatisticFromScratchSidebar.tsx @@ -7,7 +7,6 @@ import { parseISO } from "date-fns"; import { groupBy, isDefined } from "remeda"; import { useAddStatistic } from "@/lib/businessModules/statistics/api/mutations/useAddStatistic"; -import { SidebarStepper } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper"; import { CategorizedFlatAttribute, ChooseAttributesStep, @@ -21,6 +20,7 @@ import { SaveStatisticStep } from "@/lib/businessModules/statistics/components/s import { validateSaveStatisticStep } from "@/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/SaveStatisticStep/validateSaveStatisticStep"; import { CreateStatisticFromScratchFormModel } from "@/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/createStatisticFromScratchFormModel"; import { getLastXMonthsTimeRange } from "@/lib/businessModules/statistics/components/statistics/timeRangeHelper"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; export function CreateStatisticFromScratchSidebar({ open, diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/CreateStatisticFromTemplateSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/CreateStatisticFromTemplateSidebar.tsx index 045d2e27c49ed11bd7416a3334d7635a4543f199..49160ceb6828c3562c11a52c86058f4b74ada21c 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/CreateStatisticFromTemplateSidebar.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/CreateStatisticFromTemplateSidebar.tsx @@ -7,7 +7,6 @@ import { parseISO } from "date-fns"; import { groupBy, isDefined } from "remeda"; import { useAddStatistic } from "@/lib/businessModules/statistics/api/mutations/useAddStatistic"; -import { SidebarStepper } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper"; import { ChooseTemplateStep, Scheme, @@ -17,6 +16,7 @@ import { SaveStatisticStep } from "@/lib/businessModules/statistics/components/s import { validateSaveStatisticStep } from "@/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/SaveStatisticStep/validateSaveStatisticStep"; import { CreateStatisticFromTemplateFormModel } from "@/lib/businessModules/statistics/components/statistics/CreateStatisticSidebar/createStatisticFromTemplateFormModel"; import { getLastXMonthsTimeRange } from "@/lib/businessModules/statistics/components/statistics/timeRangeHelper"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; export function CreateStatisticFromTemplateSidebar({ open, diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/DuplicateStatisticSidebar/DuplicateStatisticSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/DuplicateStatisticSidebar/DuplicateStatisticSidebar.tsx index 689442e43a2ec744f639f791bc787958c2a34801..ed565d259789929a4e69ac33ef599a3acdee26e3 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/DuplicateStatisticSidebar/DuplicateStatisticSidebar.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/DuplicateStatisticSidebar/DuplicateStatisticSidebar.tsx @@ -4,10 +4,10 @@ */ import { useDuplicateStatistic } from "@/lib/businessModules/statistics/api/mutations/useDuplicateStatistic"; -import { SidebarStepper } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper"; -import { SidebarStep } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/sidebarStep"; import { DuplicateStatisticFormModel } from "@/lib/businessModules/statistics/components/statistics/DuplicateStatisticSidebar/duplicateStatisticFormModel"; import { UpdateDiagramFormModel } from "@/lib/businessModules/statistics/components/statistics/details/UpdateDiagramSidebar/updateDiagramFormModel"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; +import { SidebarStep } from "@/lib/shared/components/SidebarStepper/sidebarStep"; import { DuplicateStatisticStep } from "./DuplicateStatisticStep"; diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateDiagramSidebar/CreateDiagramSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateDiagramSidebar/CreateDiagramSidebar.tsx index 1fd5f8fd9265e3a18ba09a9302634d38d84031ff..88ddfad7f0a4442efc49f3aa6fd9fa0685e5f474 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateDiagramSidebar/CreateDiagramSidebar.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateDiagramSidebar/CreateDiagramSidebar.tsx @@ -9,11 +9,11 @@ import { useAddFilterTemplate } from "@/lib/businessModules/statistics/api/mutat import { useDeleteFilterTemplate } from "@/lib/businessModules/statistics/api/mutations/useDeleteFilterTemplate"; import { useGetFilterTemplateFilters } from "@/lib/businessModules/statistics/api/mutations/useGetFilterTemplateFilters"; import { useGetFilterTemplates } from "@/lib/businessModules/statistics/api/queries/useGetFilterTemplates"; -import { SidebarStepper } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper"; -import { SidebarStep } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/sidebarStep"; import { SaveDiagramStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateDiagramSidebar/SaveDiagramStep/SaveDiagramStep"; import { SetFiltersStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateDiagramSidebar/SetFiltersStep/SetFiltersStep"; import { CreateDiagramFormModel } from "@/lib/businessModules/statistics/components/statistics/details/CreateDiagramSidebar/createDiagramFormModel"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; +import { SidebarStep } from "@/lib/shared/components/SidebarStepper/sidebarStep"; import { UseFilterSettings } from "@/lib/shared/components/filterSettings/useFilterSettings"; import { UseFilterTemplateProps } from "@/lib/shared/components/filterSettings/useFilterTemplate"; diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/ConfigureBarChartStep/validateConfigureBarChartStep.ts b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/ConfigureBarChartStep/validateConfigureBarChartStep.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a9f4fa46dbca74e4fdb95addf719b220a59a76b --- /dev/null +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/ConfigureBarChartStep/validateConfigureBarChartStep.ts @@ -0,0 +1,27 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { FormikErrors } from "formik"; + +import { DiagramType } from "@/lib/businessModules/statistics/api/models/statisticDetailsViewTypes"; +import { CreateEvaluationFormModel } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/createEvaluationFormModel"; + +export function validateConfigureBarChartStep( + model: CreateEvaluationFormModel, +): FormikErrors<object> | undefined { + if ( + model.diagramType === DiagramType.BAR_CHART && + model.configureBarChartFormModel.primaryAttributeSelectionKey === + model.configureBarChartFormModel.secondaryAttributeSelectionKey && + model.configureBarChartFormModel.primaryAttributeSelectionKey !== null + ) { + return { + attributesMayNotMatch: + "Das primäre und sekundäre Attribut darf nicht identisch sein.", + }; + } + + return undefined; +} diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/CreateEvaluationSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/CreateEvaluationSidebar.tsx index 44d1e99b33df929055f74b40ba2cabcb02b273bc..5bb1aa24369be79f15de8fb6d1016a3af9f889fa 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/CreateEvaluationSidebar.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/CreateEvaluationSidebar.tsx @@ -8,9 +8,8 @@ import { GeoShapeInfo } from "@/lib/businessModules/statistics/api/models/geoSha import { DiagramType } from "@/lib/businessModules/statistics/api/models/statisticDetailsViewTypes"; import { useAddDiagram } from "@/lib/businessModules/statistics/api/mutations/useAddDiagram"; import { useAddEvaluation } from "@/lib/businessModules/statistics/api/mutations/useAddEvaluation"; -import { SidebarStepper } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper"; -import { SidebarStep } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/sidebarStep"; import { ConfigureBarChartStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/ConfigureBarChartStep/ConfigureBarChartStep"; +import { validateConfigureBarChartStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/ConfigureBarChartStep/validateConfigureBarChartStep"; import { ConfigureChoroplethChartStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/ConfigureChoroplethChartStep/ConfigureChoroplethChartStep"; import { ConfigureHistogramChartStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/ConfigureHistogramChartStep/ConfigureHistogramChartStep"; import { ConfigureLineChartStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/ConfigureLineChartStep/ConfigureLineChartStep"; @@ -19,6 +18,8 @@ import { ConfigureScatterChartStep } from "@/lib/businessModules/statistics/comp import { SaveEvaluationStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/SaveEvaluationStep/SaveEvaluationStep"; import { SelectDiagramStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/SelectDiagramStep/SelectDiagramStep"; import { CreateEvaluationFormModel } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/createEvaluationFormModel"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; +import { SidebarStep } from "@/lib/shared/components/SidebarStepper/sidebarStep"; export function CreateEvaluationSidebar({ open, @@ -130,6 +131,7 @@ export function CreateEvaluationSidebar({ return { title: "Balkendiagramm konfigurieren", content: <ConfigureBarChartStep attributes={attributes} />, + validator: validateConfigureBarChartStep, }; case DiagramType.PIE_CHART: return { diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/DetailsInformationCard.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/DetailsInformationCard.tsx index 62c90d99fe9c1747211f1ad49aa57ebce79a4901..aa6ac5a3a8caa7ede864ce204eb1612ae3814d37 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/DetailsInformationCard.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/DetailsInformationCard.tsx @@ -4,10 +4,11 @@ */ import { formatDate } from "@eshg/lib-portal/formatters/dateTime"; -import { AddchartOutlined } from "@mui/icons-material"; +import { AddchartOutlined, Edit } from "@mui/icons-material"; import { Button, Stack } from "@mui/joy"; import { useStatisticRoleChecks } from "@/lib/businessModules/statistics/components/statistics/useStatisticRoleChecks"; +import { ActionsMenu } from "@/lib/shared/components/buttons/ActionsMenu"; import { InfoTile } from "@/lib/shared/components/infoTile/InfoTile"; import { LabelValuePair, @@ -22,10 +23,13 @@ export interface DetailsInformationCardProps { createdBy: string; onEvaluationCreateClicked: () => void; onDataBasisUpdateClicked: () => void; + onNameChangeClicked: () => void; } export function DetailsInformationCard(props: DetailsInformationCardProps) { const canWrite = useStatisticRoleChecks().canWrite(); + // TODO: ISSUE-5587: Add once it exists + const statisticNameChangeFeatureToggle = false; return ( <InfoTile @@ -58,6 +62,20 @@ export function DetailsInformationCard(props: DetailsInformationCardProps) { </Stack> ) } + controls={ + canWrite && + statisticNameChangeFeatureToggle && ( + <ActionsMenu + actionItems={[ + { + label: "Name ändern", + onClick: () => props.onNameChangeClicked(), + startDecorator: <Edit />, + }, + ]} + /> + ) + } > <Stack gap={1}> <LabelValuePair diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/StatisticDetails.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/StatisticDetails.tsx index e3b23019162a11748cf8a87510676c60fb13bc67..056f3d6db072b535669c52997baa04e63c1954d7 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/StatisticDetails.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/StatisticDetails.tsx @@ -17,6 +17,7 @@ import { CreateDiagramSidebar } from "@/lib/businessModules/statistics/component import { CreateEvaluationSidebar } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/CreateEvaluationSidebar"; import { DetailsInformationCardProps } from "@/lib/businessModules/statistics/components/statistics/details/DetailsInformationCard"; import { InformationCards } from "@/lib/businessModules/statistics/components/statistics/details/InformationCards"; +import { StatisticNameChangeModal } from "@/lib/businessModules/statistics/components/statistics/details/StatisticNameChangeModal"; import { UpdateStatisticDataBasisSidebar } from "@/lib/businessModules/statistics/components/statistics/details/UpdateStatisticDataBasisSidebar/UpdateStatisticDataBasisSidebar"; import { OverlayBoundary } from "@/lib/shared/components/boundaries/OverlayBoundary"; import { businessModuleNames } from "@/lib/shared/components/procedures/constants"; @@ -30,6 +31,7 @@ export function StatisticDetails( useState(false); const [isUpdateDataBasisSidebarOpen, setIsUpdateDataBasisSidebarOpen] = useState(false); + const [isNameChangeModalOpen, setIsNameChangeModalOpen] = useState(false); const [createDiagramSidebarState, setCreateDiagramSidebarState] = useState< SidebarState<{ evaluationId: string }> >({ open: false }); @@ -41,6 +43,7 @@ export function StatisticDetails( createdBy: props.createdBy, onEvaluationCreateClicked: () => setIsCreateEvaluationSidebarOpen(true), onDataBasisUpdateClicked: () => setIsUpdateDataBasisSidebarOpen(true), + onNameChangeClicked: () => setIsNameChangeModalOpen(true), }; const businessModuleInformationCardsProps: BusinessModuleInformationCardProps[] = @@ -93,6 +96,13 @@ export function StatisticDetails( </OverlayBoundary> )} + <OverlayBoundary> + <StatisticNameChangeModal + open={isNameChangeModalOpen} + onClose={() => setIsNameChangeModalOpen(false)} + initialName={props.title} + /> + </OverlayBoundary> <InformationCards detailsInformationCardProps={detailsInformationCardProps} businessModuleInformationCardsProps={ diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/StatisticNameChangeModal.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/StatisticNameChangeModal.tsx new file mode 100644 index 0000000000000000000000000000000000000000..7718e4f35a4038810affef787fb9d02de29a79b2 --- /dev/null +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/StatisticNameChangeModal.tsx @@ -0,0 +1,46 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { InputField } from "@eshg/lib-portal/components/formFields/InputField"; + +import { useEditStatisticName } from "@/lib/businessModules/statistics/api/mutations/useEditStatisticName"; +import { FormDialog } from "@/lib/shared/components/formDialog/FormDialog"; + +interface StatisticNameChangeModalProps { + open: boolean; + onClose: () => void; + initialName: string; +} + +export function StatisticNameChangeModal(props: StatisticNameChangeModalProps) { + const editStatisticName = useEditStatisticName(); + + async function onSubmit(model: { name: string }) { + return editStatisticName(model.name).then(() => props.onClose()); + } + + return ( + <FormDialog + open={props.open} + onClose={props.onClose} + onSubmit={onSubmit} + initialValues={{ + name: props.initialName, + }} + title="Name ändern" + description="Wählen Sie einen neuen Namen für die Statistik." + color="primary" + confirmLabel="Speichern" + cancelLabel="Abbrechen" + > + <InputField + name="name" + label="Name der Statistik" + required="Bitte neuen Namen angeben." + sx={{ marginTop: 2 }} + /> + </FormDialog> + ); +} diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateDiagramSidebar/UpdateDiagramSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateDiagramSidebar/UpdateDiagramSidebar.tsx index 0a912e53ef86174bbebd659791697af476e858a2..4dfce888d035497575bc859b5e8d91872d873734 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateDiagramSidebar/UpdateDiagramSidebar.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateDiagramSidebar/UpdateDiagramSidebar.tsx @@ -4,10 +4,10 @@ */ import { useUpdateDiagram } from "@/lib/businessModules/statistics/api/mutations/useUpdateDiagram"; -import { SidebarStepper } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper"; -import { SidebarStep } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/sidebarStep"; import { SaveDiagramStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateDiagramSidebar/SaveDiagramStep/SaveDiagramStep"; import { UpdateDiagramFormModel } from "@/lib/businessModules/statistics/components/statistics/details/UpdateDiagramSidebar/updateDiagramFormModel"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; +import { SidebarStep } from "@/lib/shared/components/SidebarStepper/sidebarStep"; export function UpdateDiagramSidebar(props: { open: boolean; diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateEvaluationSidebar/UpdateEvaluationSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateEvaluationSidebar/UpdateEvaluationSidebar.tsx index bb4db2a429bd1196db5ca8e362096a187746f618..26ebb3cbd9346df102f6b6f09c50e10e84dfa382 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateEvaluationSidebar/UpdateEvaluationSidebar.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateEvaluationSidebar/UpdateEvaluationSidebar.tsx @@ -4,10 +4,10 @@ */ import { useUpdateEvaluation } from "@/lib/businessModules/statistics/api/mutations/useUpdateEvaluation"; -import { SidebarStepper } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper"; -import { SidebarStep } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/sidebarStep"; import { SaveEvaluationStep } from "@/lib/businessModules/statistics/components/statistics/details/CreateEvaluationSidebar/SaveEvaluationStep/SaveEvaluationStep"; import { UpdateEvaluationFormModel } from "@/lib/businessModules/statistics/components/statistics/details/UpdateEvaluationSidebar/updateEvaluationFormModel"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; +import { SidebarStep } from "@/lib/shared/components/SidebarStepper/sidebarStep"; export function UpdateEvaluationSidebar(props: { open: boolean; diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateStatisticDataBasisSidebar/UpdateStatisticDataBasisSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateStatisticDataBasisSidebar/UpdateStatisticDataBasisSidebar.tsx index 9441415e6b875f23c22d24457fcba13783e4acef..1d79c7fc05d13fb4f65fa051cb7c47df64251b09 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateStatisticDataBasisSidebar/UpdateStatisticDataBasisSidebar.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/UpdateStatisticDataBasisSidebar/UpdateStatisticDataBasisSidebar.tsx @@ -5,7 +5,7 @@ import { Alert } from "@eshg/lib-portal/components/Alert"; -import { SidebarStepper } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; import { useConfirmationDialog } from "@/lib/shared/components/confirmationDialog/ConfirmationDialogProvider"; import { UpdateStatisticDataBasisStep } from "./UpdateStatisticDataBasisStep"; diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/reports/AddReportSidebar/AddReportSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/reports/AddReportSidebar/AddReportSidebar.tsx index debb93af423b0dfdc903ac244ff1a4dab4c08a8e..31762d21910f82c5bb47c2e4f48b7882171dd8dc 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/reports/AddReportSidebar/AddReportSidebar.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/reports/AddReportSidebar/AddReportSidebar.tsx @@ -4,10 +4,10 @@ */ import { useAddReport } from "@/lib/businessModules/statistics/api/mutations/useAddReport"; -import { SidebarStepper } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper"; import { SaveReportStep } from "@/lib/businessModules/statistics/components/statistics/details/reports/AddReportSidebar/SaveReportStep"; import { AddReportFormModel } from "@/lib/businessModules/statistics/components/statistics/details/reports/AddReportSidebar/addReportFormModel"; import { getLastXMonthsTimeRange } from "@/lib/businessModules/statistics/components/statistics/timeRangeHelper"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; export function AddReportSidebar({ onClose, diff --git a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/reports/UpdateReportSidebar/UpdateReportSidebar.tsx b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/reports/UpdateReportSidebar/UpdateReportSidebar.tsx index 0005098c5695d0cf89acca026206f1dee64275e8..0b03e63f033b68d223833dd3c4c19f1c6f34f515 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/statistics/details/reports/UpdateReportSidebar/UpdateReportSidebar.tsx +++ b/employee-portal/src/lib/businessModules/statistics/components/statistics/details/reports/UpdateReportSidebar/UpdateReportSidebar.tsx @@ -4,9 +4,9 @@ */ import { useUpdateReport } from "@/lib/businessModules/statistics/api/mutations/useUpdateReport"; -import { SidebarStepper } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper"; import { UpdateReportStep } from "@/lib/businessModules/statistics/components/statistics/details/reports/UpdateReportSidebar/UpdateReportStep"; import { UpdateReportFormModel } from "@/lib/businessModules/statistics/components/statistics/details/reports/UpdateReportSidebar/updateReportFormModel"; +import { SidebarStepper } from "@/lib/shared/components/SidebarStepper/SidebarStepper"; export interface UpdateReportSidebarReportInfo { seriesId: string; diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/clients.ts b/employee-portal/src/lib/businessModules/stiProtection/api/clients.ts index c521170b25bf11db099feb38fe4df048bcbe2735..db5531d3bd2e845b73b267b0044ae007288cf2d8 100644 --- a/employee-portal/src/lib/businessModules/stiProtection/api/clients.ts +++ b/employee-portal/src/lib/businessModules/stiProtection/api/clients.ts @@ -5,7 +5,9 @@ import { AppointmentBlockApi, + AppointmentTypeApi, ApprovalRequestApi, + ArchivingApi, Configuration, FileApi, ProcedureApi, @@ -50,3 +52,13 @@ export function useAppointmentBlockApi() { const configuration = useConfiguration(); return new AppointmentBlockApi(configuration); } + +export function useAppointmentTypeApi() { + const configuration = useConfiguration(); + return new AppointmentTypeApi(configuration); +} + +export function useArchivingApi() { + const configuration = useConfiguration(); + return new ArchivingApi(configuration); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/models/AppointmentBlockGroup.ts b/employee-portal/src/lib/businessModules/stiProtection/api/models/AppointmentBlockGroup.ts index f85f9392c0abac3ab30f8f1043fcbe17cb07ed2f..d288b15f4c27cc67b96f78f3ac48fd6c466d0b94 100644 --- a/employee-portal/src/lib/businessModules/stiProtection/api/models/AppointmentBlockGroup.ts +++ b/employee-portal/src/lib/businessModules/stiProtection/api/models/AppointmentBlockGroup.ts @@ -30,6 +30,18 @@ export type AppointmentDurationsStiProtection = Record< number >; +export function mapAppointmentBlock( + response: ApiGetAppointmentBlock, +): AppointmentBlockStiProtection { + return { + ...mapBaseEntity(response), + start: response.start, + end: response.end, + numberOfFreeAppointments: response.numberOfFreeAppointments, + numberOfBookedAppointments: response.numberOfBookedAppointments, + }; +} + export function mapAppointmentBlockGroup( response: ApiGetAppointmentBlockGroup, ): AppointmentBlockGroup { @@ -56,15 +68,3 @@ export function mapAppointmentBlockGroup( appointmentBlocks: response.appointmentBlocks.map(mapAppointmentBlock), }; } - -export function mapAppointmentBlock( - response: ApiGetAppointmentBlock, -): AppointmentBlockStiProtection { - return { - ...mapBaseEntity(response), - start: response.start, - end: response.end, - numberOfFreeAppointments: response.numberOfFreeAppointments, - numberOfBookedAppointments: response.numberOfBookedAppointments, - }; -} diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/models/AppointmentTypeConfig.ts b/employee-portal/src/lib/businessModules/stiProtection/api/models/AppointmentTypeConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..1ea5dcb13948048f1946c6d651ec541193729f54 --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/api/models/AppointmentTypeConfig.ts @@ -0,0 +1,29 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + ApiAppointmentType, + ApiAppointmentTypeConfig, +} from "@eshg/employee-portal-api/stiProtection"; + +import { + BaseEntity, + mapBaseEntity, +} from "@/lib/businessModules/stiProtection/api/models/BaseEntity"; + +export interface AppointmentTypeConfig extends BaseEntity { + appointmentTypeDto: ApiAppointmentType; + standardDurationInMinutes: number; +} + +export function mapAppointmentTypeConfig( + response: ApiAppointmentTypeConfig, +): AppointmentTypeConfig { + return { + ...mapBaseEntity(response), + appointmentTypeDto: response.appointmentTypeDto, + standardDurationInMinutes: response.standardDurationInMinutes, + }; +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/mutations/appointmentBlocks.ts b/employee-portal/src/lib/businessModules/stiProtection/api/mutations/appointmentBlocks.ts new file mode 100644 index 0000000000000000000000000000000000000000..c46308c1d7e23375a73de470c09760a2e1d7cacd --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/api/mutations/appointmentBlocks.ts @@ -0,0 +1,27 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { ApiCreateDailyAppointmentBlockGroupRequest } from "@eshg/employee-portal-api/stiProtection"; +import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; +import { useMutation } from "@tanstack/react-query"; + +import { useAppointmentBlockApi } from "@/lib/businessModules/stiProtection/api/clients"; +import { appointmentBlockApiQueryKey } from "@/lib/businessModules/stiProtection/api/queries/apiQueryKeys"; + +export function useCreateDailyAppointmentBlocksForGroup() { + const appointmentBlockGroupsApi = useAppointmentBlockApi(); + const snackbar = useSnackbar(); + return useMutation({ + mutationFn: (request: ApiCreateDailyAppointmentBlockGroupRequest) => + appointmentBlockGroupsApi.createDailyAppointmentBlocksForGroup(request), + onSuccess: () => { + snackbar.confirmation("Der Terminblock wurde erfolgreich geplant."); + }, + onError: () => { + snackbar.error("Der Terminblock konnte nicht angelegt werden."); + }, + mutationKey: appointmentBlockApiQueryKey(["appointmentBlockGroups"]), + }); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/mutations/appointmentTypes.ts b/employee-portal/src/lib/businessModules/stiProtection/api/mutations/appointmentTypes.ts new file mode 100644 index 0000000000000000000000000000000000000000..0e62d5fd6b2b459498d787981c8b430b2628d92b --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/api/mutations/appointmentTypes.ts @@ -0,0 +1,35 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + ApiAppointmentTypeConfig, + ApiUpdateAppointmentTypeRequest, +} from "@eshg/employee-portal-api/stiProtection"; +import { useHandledMutation } from "@eshg/lib-portal/api/useHandledMutation"; + +import { useAppointmentTypeApi } from "@/lib/businessModules/stiProtection/api/clients"; + +import { MutationPassThrough } from "./types"; + +export interface UpdateAppointmentTypeRequestArgs { + request: ApiUpdateAppointmentTypeRequest; + id: string; +} + +export function useUpdateAppointmentType({ + onSuccess, + onError, +}: MutationPassThrough< + ApiAppointmentTypeConfig, + UpdateAppointmentTypeRequestArgs +> = {}) { + const appointmentTypeApi = useAppointmentTypeApi(); + return useHandledMutation({ + mutationFn: ({ id, request }: UpdateAppointmentTypeRequestArgs) => + appointmentTypeApi.updateAppointmentType(id, request), + onSuccess, + onError, + }); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/mutations/archiving.ts b/employee-portal/src/lib/businessModules/stiProtection/api/mutations/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..c287724eb2999ad3457d41f1e9be23fbe345b0d6 --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/api/mutations/archiving.ts @@ -0,0 +1,18 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useArchivingApi } from "@/lib/businessModules/stiProtection/api/clients"; +import { + useBulkUpdateProceduresArchivingRelevanceTemplate, + useExportRelevantProceduresTemplate, +} from "@/lib/shared/api/mutations/archiving"; + +export function useBulkUpdateProceduresArchivingRelevance() { + return useBulkUpdateProceduresArchivingRelevanceTemplate(useArchivingApi); +} + +export function useExportRelevantProcedures() { + return useExportRelevantProceduresTemplate(useArchivingApi); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/queries/apiQueryKeys.ts b/employee-portal/src/lib/businessModules/stiProtection/api/queries/apiQueryKeys.ts index b9bdb9912652184a912d5723392a332f9e657e65..0204a8a1b0016e422dca9be42d29d69a73486c74 100644 --- a/employee-portal/src/lib/businessModules/stiProtection/api/queries/apiQueryKeys.ts +++ b/employee-portal/src/lib/businessModules/stiProtection/api/queries/apiQueryKeys.ts @@ -11,14 +11,26 @@ export const appointmentBlockApiQueryKey = queryKeyFactory( stiProtectionApiQueryKey(["appointmentBlockApi"]), ); -export const stiProtectionProceduresApiQueryKey = queryKeyFactory( - stiProtectionApiQueryKey(["stiProcedures"]), +export const appointmentStaffApiQueryKey = queryKeyFactory( + stiProtectionApiQueryKey(["appointmentStaffApi"]), +); + +export const fileApiQueryKey = queryKeyFactory( + stiProtectionApiQueryKey(["fileApi"]), ); export const progressEntryApiQueryKey = queryKeyFactory( stiProtectionApiQueryKey(["progressEntryApi"]), ); -export const fileApiQueryKey = queryKeyFactory( - stiProtectionApiQueryKey(["fileApi"]), +export const stiProtectionProceduresApiQueryKey = queryKeyFactory( + stiProtectionApiQueryKey(["stiProcedures"]), +); + +export const appointmentTypesApiQueryKey = queryKeyFactory( + stiProtectionApiQueryKey(["appointmentTypes"]), +); + +export const archivingApiQueryKey = queryKeyFactory( + stiProtectionApiQueryKey(["archivingApi"]), ); diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/queries/appointmentBlocks.ts b/employee-portal/src/lib/businessModules/stiProtection/api/queries/appointmentBlocks.ts index 36c214110769710c3d3043661ee0d064cbb77290..d29c33d741a303db5a0e608b4859e98ec1b87298 100644 --- a/employee-portal/src/lib/businessModules/stiProtection/api/queries/appointmentBlocks.ts +++ b/employee-portal/src/lib/businessModules/stiProtection/api/queries/appointmentBlocks.ts @@ -3,9 +3,12 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { GetAppointmentBlockGroupsRequest } from "@eshg/employee-portal-api/stiProtection"; +import { + ApiCreateAppointmentBlockGroupRequest, + GetAppointmentBlockGroupsRequest, +} from "@eshg/employee-portal-api/stiProtection"; import { unwrapRawResponse } from "@eshg/lib-portal/api/unwrapRawResponse"; -import { useSuspenseQuery } from "@tanstack/react-query"; +import { useQuery, useSuspenseQuery } from "@tanstack/react-query"; import { useAppointmentBlockApi } from "@/lib/businessModules/stiProtection/api/clients"; import { mapAppointmentBlockGroup } from "@/lib/businessModules/stiProtection/api/models/AppointmentBlockGroup"; @@ -17,11 +20,9 @@ export function useGetAppointmentBlockGroups( request: GetAppointmentBlockGroupsRequest, ) { const appointmentBlockApi = useAppointmentBlockApi(); + return useSuspenseQuery({ - queryKey: appointmentBlockApiQueryKey([ - "getAppointmentBlockGroups", - request, - ]), + queryKey: appointmentBlockApiQueryKey(["appointmentBlockGroups", request]), queryFn: () => appointmentBlockApi .getAppointmentBlockGroupsRaw(request) @@ -29,3 +30,20 @@ export function useGetAppointmentBlockGroups( select: mapPaginatedList(mapAppointmentBlockGroup), }); } + +export function useValidateAppointmentBlockGroup( + request: ApiCreateAppointmentBlockGroupRequest | null, +) { + const appointmentBlockApi = useAppointmentBlockApi(); + + return useQuery({ + queryKey: appointmentBlockApiQueryKey([ + "validateAppointmentBlockGroup", + request, + ]), + queryFn: () => + request != null + ? appointmentBlockApi.validateAppointmentBlockGroup(request) + : null, + }); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/queries/appointmentStaff.ts b/employee-portal/src/lib/businessModules/stiProtection/api/queries/appointmentStaff.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8e9bc4fa65a9553ae0eae4911a3cdfc13c2c720 --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/api/queries/appointmentStaff.ts @@ -0,0 +1,33 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + ApiGetUsersResponse, + ApiUser, + UserApi, +} from "@eshg/employee-portal-api/base"; +import { queryOptions } from "@tanstack/react-query"; + +import { appointmentStaffApiQueryKey } from "./apiQueryKeys"; + +export function getAllPhysiciansQuery(userApi: UserApi) { + return queryOptions({ + queryKey: appointmentStaffApiQueryKey(["physicians"]), + queryFn: () => userApi.getUsersByGroup("[System] HIV-STI-Arzt"), + select: mapUsers, + }); +} + +export function getAllConsultantsQuery(userApi: UserApi) { + return queryOptions({ + queryKey: appointmentStaffApiQueryKey(["consultants"]), + queryFn: () => userApi.getUsersByGroup("[System] HIV-STI-Berater"), + select: mapUsers, + }); +} + +function mapUsers(response: ApiGetUsersResponse): ApiUser[] { + return response.users; +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/queries/appointmentTypes.ts b/employee-portal/src/lib/businessModules/stiProtection/api/queries/appointmentTypes.ts new file mode 100644 index 0000000000000000000000000000000000000000..e2be582e14e4b3f4e656e22d273f52b871594090 --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/api/queries/appointmentTypes.ts @@ -0,0 +1,33 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { AppointmentTypeApi } from "@eshg/employee-portal-api/stiProtection"; +import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; + +import { useAppointmentTypeApi } from "@/lib/businessModules/stiProtection/api/clients"; +import { appointmentTypesApiQueryKey } from "@/lib/businessModules/stiProtection/api/queries/apiQueryKeys"; + +export function getAllAppointmentTypesQuery( + appointmentTypesApi: AppointmentTypeApi, +) { + return queryOptions({ + queryKey: appointmentTypesApiQueryKey(["appointmentTypes"]), + queryFn: () => appointmentTypesApi.getAppointmentTypes(), + select: (response) => response.appointmentTypeConfigDtos ?? [], + }); +} + +export function useGetAllAppointmentTypes() { + const appointmentTypeApi = useAppointmentTypeApi(); + return useSuspenseQuery(getAllAppointmentTypesQuery(appointmentTypeApi)); +} + +export function useGetOneAppointmentType(id: string) { + const appointmentTypeApi = useAppointmentTypeApi(); + return useSuspenseQuery({ + queryKey: appointmentTypesApiQueryKey(["getOneAppointmentType", id]), + queryFn: () => appointmentTypeApi.getOneAppointmentType(id), + }); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/api/queries/archiving.ts b/employee-portal/src/lib/businessModules/stiProtection/api/queries/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..9ef2e306d5453bc7494d7084b63dc75c8ca665c8 --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/api/queries/archiving.ts @@ -0,0 +1,43 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + GetArchivableProceduresRequest, + GetRelevantArchivableProceduresRequest, +} from "@eshg/employee-portal-api/businessProcedures"; + +import { useArchivingApi } from "@/lib/businessModules/stiProtection/api/clients"; +import { archivingApiQueryKey } from "@/lib/businessModules/stiProtection/api/queries/apiQueryKeys"; +import { + useGetArchivableProceduresTemplate, + useGetArchivingConfigurationTemplate, + useGetRelevantArchivableProceduresTemplate, +} from "@/lib/shared/api/queries/archiving"; + +export function useGetArchivingConfiguration() { + return useGetArchivingConfigurationTemplate( + useArchivingApi, + archivingApiQueryKey, + ); +} +export function useGetArchivableProcedures( + request: GetArchivableProceduresRequest, +) { + return useGetArchivableProceduresTemplate( + useArchivingApi, + archivingApiQueryKey, + request, + ); +} + +export function useGetRelevantArchivableProcedures( + request: GetRelevantArchivableProceduresRequest, +) { + return useGetRelevantArchivableProceduresTemplate( + useArchivingApi, + archivingApiQueryKey, + request, + ); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/AppointmentBlockGroupForm.tsx b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/AppointmentBlockGroupForm.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d2f52f1146b63c3fce8db6cd090abd9f4a4380ce --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/AppointmentBlockGroupForm.tsx @@ -0,0 +1,166 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + ApiAppointmentType, + ApiAppointmentTypeConfig, + ApiUser, +} from "@eshg/employee-portal-api/stiProtection"; +import { SelectOption } from "@eshg/lib-portal/components/formFields/SelectOptions"; +import { OptionalFieldValue } from "@eshg/lib-portal/types/form"; +import { Divider, Stack } from "@mui/joy"; +import { Formik, FormikErrors } from "formik"; +import { isDefined, isEmpty, mapToObj } from "remeda"; + +import { AppointmentTypeConfig } from "@/lib/businessModules/stiProtection/api/models/AppointmentTypeConfig"; +import { routes } from "@/lib/businessModules/stiProtection/shared/routes"; +import { AppointmentBlockGroupValuesWithDays } from "@/lib/shared/components/appointmentBlocks/AppointmentBlockFormWithDays"; +import { AppointmentBlockGroupFields } from "@/lib/shared/components/appointmentBlocks/AppointmentBlockGroupFields"; +import { AppointmentValues } from "@/lib/shared/components/appointmentBlocks/AppointmentCount"; +import { AppointmentCountWithDays } from "@/lib/shared/components/appointmentBlocks/AppointmentCountWithDays"; +import { AppointmentStaffSelection } from "@/lib/shared/components/appointmentBlocks/AppointmentStaffSelection"; +import { FormButtonBar } from "@/lib/shared/components/form/FormButtonBar"; +import { FormSheet } from "@/lib/shared/components/form/FormSheet"; +import { fullName } from "@/lib/shared/components/users/userFormatter"; +import { validateFieldArray } from "@/lib/shared/helpers/validators"; + +import { validateAppointmentBlock } from "./ValidateAppointmentBlock"; +import { APPOINTMENT_TYPE_OPTIONS } from "./options"; + +export interface AppointmentBlockGroupValues { + type: OptionalFieldValue<ApiAppointmentType>; + parallelExaminations: OptionalFieldValue<number>; + appointmentBlocks: AppointmentBlockGroupValuesWithDays[]; + allAppointmentTypes: AppointmentTypeConfig[]; + consultants: string[]; + physicians: string[]; + locationId: OptionalFieldValue<string>; +} + +export interface StiProtectionAppointmentValues + extends Omit< + AppointmentValues<ApiAppointmentType, ApiAppointmentTypeConfig>, + "appointmentBlocks" | "mfas" + > { + appointmentBlocks: AppointmentBlockGroupValuesWithDays[]; + consultants: string[]; +} + +function validateForm( + values: StiProtectionAppointmentValues, + appointmentTypes: AppointmentTypeConfig[], +) { + const errors: FormikErrors< + AppointmentValues<ApiAppointmentType, ApiAppointmentTypeConfig> + > = {}; + const appointmentDurations = mapToObj( + appointmentTypes, + (appointmentTypeConfig) => [ + appointmentTypeConfig.appointmentTypeDto, + appointmentTypeConfig.standardDurationInMinutes, + ], + ); + const appointmentBlockErrors = validateFieldArray( + values.appointmentBlocks, + (appointmentBlock) => + validateAppointmentBlock( + values.type, + appointmentBlock, + appointmentDurations, + ), + ); + if (isDefined(appointmentBlockErrors)) { + errors.appointmentBlocks = appointmentBlockErrors; + } + + if (isEmpty(values.physicians) && isEmpty(values.consultants)) { + const msg = + "Es muss mindestens ein:e Arzt:in oder ein:e Berater:in ausgewählt sein."; + errors.physicians = msg; + errors.mfas = msg; + } + + return errors; +} + +function userToOption(user: ApiUser): SelectOption { + return { + value: user.userId, + label: fullName(user), + }; +} + +interface AppointmentBlockGroupFormProps { + onSubmit: (values: AppointmentBlockGroupValues) => Promise<void>; + validateAvailability: (values: StiProtectionAppointmentValues) => void; + appointmentTypes: AppointmentTypeConfig[]; + blockedStaff: string[]; + freeStaff: string[]; + initialValues: StiProtectionAppointmentValues; + consultants: ApiUser[]; + physicians: ApiUser[]; +} + +export function AppointmentBlockGroupForm({ + onSubmit, + validateAvailability, + appointmentTypes, + blockedStaff, + freeStaff, + initialValues, + consultants = [], + physicians = [], +}: Readonly<AppointmentBlockGroupFormProps>) { + const physicianOptions = physicians.map(userToOption); + const consultantOptions = consultants.map(userToOption); + const appointmentDurations = Object.fromEntries( + appointmentTypes.map((currentType) => [ + currentType.appointmentTypeDto, + currentType.standardDurationInMinutes, + ]), + ); + + return ( + <Formik + initialValues={initialValues} + onSubmit={onSubmit} + validate={(values) => validateForm(values, appointmentTypes)} + > + {({ values, isSubmitting, handleSubmit }) => ( + <FormSheet onSubmit={handleSubmit}> + <Stack gap={4}> + <AppointmentBlockGroupFields + appointmentBlocksWithDays={values.appointmentBlocks} + options={APPOINTMENT_TYPE_OPTIONS} + showAppointmentBlockFieldArrayWithDays + /> + </Stack> + <Divider /> + <Stack gap={4}> + <AppointmentStaffSelection + blockedStaff={blockedStaff} + freeStaff={freeStaff} + consultantOptions={consultantOptions} + physicianOptions={physicianOptions} + validateAvailability={() => validateAvailability(values)} + /> + </Stack> + <FormButtonBar + left={ + <AppointmentCountWithDays + appointments={values} + appointmentDurations={appointmentDurations} + parallelExaminations={1} + /> + } + submitLabel="Planen" + submitting={isSubmitting} + onCancel={routes.appointmentBlockGroups.index} + /> + </FormSheet> + )} + </Formik> + ); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/AppointmentBlockGroupsTable.tsx b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/AppointmentBlockGroupsTable.tsx index 00d47a3564266b1c953e716dbc7e6e4153fe6c57..b4a4ec6a8dc5766d4017243c41c82e0eeb78b22c 100644 --- a/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/AppointmentBlockGroupsTable.tsx +++ b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/AppointmentBlockGroupsTable.tsx @@ -293,7 +293,6 @@ function NoAppointmentBlocksAvailable() { href={routes.appointmentBlockGroups.new} size="sm" startDecorator={<Schedule />} - disabled > Neuen Terminblock planen </InternalLinkButton> diff --git a/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/CreateAppointmentBlockGroupForm.tsx b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/CreateAppointmentBlockGroupForm.tsx new file mode 100644 index 0000000000000000000000000000000000000000..bca09544422b6c7397e5d32cc37ca6caac1029f8 --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/CreateAppointmentBlockGroupForm.tsx @@ -0,0 +1,162 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { + ApiAppointmentType, + ApiCreateAppointmentBlockGroupRequest, + ApiCreateDailyAppointmentBlock, + ApiCreateDailyAppointmentBlockGroupRequest, +} from "@eshg/employee-portal-api/stiProtection"; +import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; +import { mapRequiredValue } from "@eshg/lib-portal/helpers/form"; +import { useSuspenseQueries } from "@tanstack/react-query"; +import { useRouter } from "next/navigation"; +import { useEffect, useMemo, useState } from "react"; + +import { useUserApi } from "@/lib/baseModule/api/clients"; +import { useAppointmentTypeApi } from "@/lib/businessModules/stiProtection/api/clients"; +import { mapAppointmentTypeConfig } from "@/lib/businessModules/stiProtection/api/models/AppointmentTypeConfig"; +import { useCreateDailyAppointmentBlocksForGroup } from "@/lib/businessModules/stiProtection/api/mutations/appointmentBlocks"; +import { useValidateAppointmentBlockGroup } from "@/lib/businessModules/stiProtection/api/queries/appointmentBlocks"; +import { + getAllConsultantsQuery, + getAllPhysiciansQuery, +} from "@/lib/businessModules/stiProtection/api/queries/appointmentStaff"; +import { getAllAppointmentTypesQuery } from "@/lib/businessModules/stiProtection/api/queries/appointmentTypes"; +import { routes } from "@/lib/businessModules/stiProtection/shared/routes"; +import { + AppointmentBlockGroupValuesWithDays, + emptyAppointmentBlockGroup, +} from "@/lib/shared/components/appointmentBlocks/AppointmentBlockFormWithDays"; +import { toLocalDateTime } from "@/lib/shared/helpers/dateTime"; + +import { + AppointmentBlockGroupForm, + AppointmentBlockGroupValues, + StiProtectionAppointmentValues, +} from "./AppointmentBlockGroupForm"; + +const INITIAL_VALUES: StiProtectionAppointmentValues = { + type: ApiAppointmentType.HivStiConsultation, + appointmentBlocks: [emptyAppointmentBlockGroup()], + allAppointmentTypes: [], + physicians: [], + consultants: [], + parallelExaminations: 1, + locationId: "", +}; + +function mapAppointmentBlock( + values: AppointmentBlockGroupValuesWithDays, +): ApiCreateDailyAppointmentBlock { + return { + daysOfWeek: values.daysOfWeek, + start: toLocalDateTime(values.startDate, values.startTime), + end: toLocalDateTime(values.endDate, values.endTime), + }; +} + +function mapFormValues( + values: StiProtectionAppointmentValues, +): ApiCreateDailyAppointmentBlockGroupRequest { + return { + type: mapRequiredValue(values.type), + parallelExaminations: 1, + appointmentBlocks: values.appointmentBlocks.map(mapAppointmentBlock), + physicians: values.physicians, + consultants: values.consultants, + }; +} + +export function CreateAppointmentBlockGroupForm() { + const router = useRouter(); + const snackbar = useSnackbar(); + const userApi = useUserApi(); + const appointmentTypeApi = useAppointmentTypeApi(); + const createDailyAppointmentBlocksForGroup = + useCreateDailyAppointmentBlocksForGroup(); + + const [validateRequest, setValidateRequest] = + useState<ApiCreateAppointmentBlockGroupRequest | null>(null); + const [freeStaff, setFreeStaff] = useState<string[]>([]); + const [blockedStaff, setBlockedStaff] = useState<string[]>([]); + + const validateAppointmentBlockGroup = + useValidateAppointmentBlockGroup(validateRequest); + const [ + { data: allAppointmentTypesData }, + { data: allPhysicians }, + { data: allConsultants }, + ] = useSuspenseQueries({ + queries: [ + getAllAppointmentTypesQuery(appointmentTypeApi), + getAllPhysiciansQuery(userApi), + getAllConsultantsQuery(userApi), + ], + }); + + const allAppointmentTypes = useMemo( + () => allAppointmentTypesData.map(mapAppointmentTypeConfig), + [allAppointmentTypesData], + ); + const initialValues = { + ...INITIAL_VALUES, + allAppointmentTypes: allAppointmentTypesData, + }; + + useEffect(() => { + if (validateAppointmentBlockGroup.data) { + const result = validateAppointmentBlockGroup.data; + setFreeStaff(result.userIdsWithoutEventConflicts); + setBlockedStaff(result.userIdsWithEventConflicts); + } + }, [validateAppointmentBlockGroup]); + + function validateAvailability(values: StiProtectionAppointmentValues) { + try { + mapFormValues(values); + } catch { + snackbar.notification( + "Bitte Terminblöcke für die Validierung konfigurieren", + ); + return; + } + if (values.physicians.length == 0 && values.consultants.length == 0) { + snackbar.notification( + "Bitte mindestens ein:e Arzt:in oder ein:e Berater:in für die Validierung auswählen", + ); + return; + } + setValidateRequest(mapFormValues(values)); + } + + async function handleSubmit(values: AppointmentBlockGroupValues) { + const appointmentBlockGroupValues = mapFormValues(values); + await createDailyAppointmentBlocksForGroup + .mutateAsync(appointmentBlockGroupValues, { + onSuccess: () => { + router.push(routes.appointmentBlockGroups.index); + }, + }) + .catch(); + } + + return ( + <AppointmentBlockGroupForm + initialValues={initialValues} + appointmentTypes={allAppointmentTypes} + freeStaff={freeStaff} + blockedStaff={blockedStaff} + consultants={allConsultants} + physicians={allPhysicians} + onSubmit={async (values) => { + await handleSubmit(values); + }} + validateAvailability={validateAvailability} + /> + ); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/ValidateAppointmentBlock.ts b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/ValidateAppointmentBlock.ts new file mode 100644 index 0000000000000000000000000000000000000000..44b326abc20df3500acc0523ad0a1376233d2996 --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/ValidateAppointmentBlock.ts @@ -0,0 +1,76 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { ApiAppointmentType } from "@eshg/employee-portal-api/schoolEntry"; +import { isEmptyString } from "@eshg/lib-portal/helpers/guards"; +import { OptionalFieldValue } from "@eshg/lib-portal/types/form"; +import { differenceInCalendarDays, isBefore, isEqual, isPast } from "date-fns"; +import { FormikErrors } from "formik"; +import { isEmpty } from "remeda"; + +import { getAppointmentDurationInMinutes } from "@/lib/businessModules/measlesProtection/shared/helpers"; +import { AppointmentDurationsStiProtection } from "@/lib/businessModules/stiProtection/api/models/AppointmentBlockGroup"; +import { AppointmentBlockGroupValuesWithDays } from "@/lib/shared/components/appointmentBlocks/AppointmentBlockFormWithDays"; +import { calculateAppointmentsPerBlock } from "@/lib/shared/components/appointmentBlocks/AppointmentCountWithDays"; +import { toLocalDateTime } from "@/lib/shared/helpers/dateTime"; + +const MAX_DAYS_IN_APPOINTMENT_BLOCK = 31; + +export function validateAppointmentBlock( + type: OptionalFieldValue<ApiAppointmentType>, + appointmentBlock: AppointmentBlockGroupValuesWithDays, + appointmentDurationsStiProtection: AppointmentDurationsStiProtection, +) { + const { startDate, endDate, startTime, endTime, daysOfWeek } = + appointmentBlock; + const errors: FormikErrors<AppointmentBlockGroupValuesWithDays> = {}; + if ( + isEmpty(startDate) || + isEmpty(endDate) || + isEmpty(startTime) || + isEmpty(endTime) || + !daysOfWeek.length + ) { + return errors; + } + + const start = toLocalDateTime(startDate, startTime); + + if (isPast(start)) { + errors.startTime = "Die Startzeit liegt in der Vergangenheit."; + } + + const end = toLocalDateTime(endDate, endTime); + const dailyStartTime = toLocalDateTime(startDate, startTime); + const dailyEndTime = toLocalDateTime(startDate, endTime); + + if (isEqual(dailyStartTime, dailyEndTime)) { + errors.endTime = "Die Endzeit ist identisch zur Startzeit."; + } else if (isBefore(dailyEndTime, dailyStartTime)) { + errors.endTime = "Die Endzeit liegt vor der Startzeit."; + } else if (isBefore(end, start)) { + errors.endDate = "Das Enddatum liegt vor dem Startdatum."; + } else if ( + differenceInCalendarDays(endDate, startDate) > MAX_DAYS_IN_APPOINTMENT_BLOCK + ) { + errors.endDate = `Der Datumsbereich für einen Terminblock ist auf ${MAX_DAYS_IN_APPOINTMENT_BLOCK} Tage begrenzt.`; + } else if ( + !isEmptyString(type) && + calculateAppointmentsPerBlock( + type, + start, + end, + appointmentDurationsStiProtection, + ) === 0 + ) { + const appointmentDurationInMinutes = getAppointmentDurationInMinutes( + type, + appointmentDurationsStiProtection, + ); + errors.endTime = `Die Dauer ist nicht teilbar durch die Terminlänge von ${appointmentDurationInMinutes} Minuten.`; + } + + return errors; +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/options.ts b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/options.ts new file mode 100644 index 0000000000000000000000000000000000000000..513dfe89352692a35cbf198ff74b4cea4e77cb20 --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentBlocks/options.ts @@ -0,0 +1,19 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { ApiAppointmentType } from "@eshg/employee-portal-api/stiProtection"; +import { buildEnumOptions } from "@eshg/lib-portal/helpers/form"; + +import { APPOINTMENT_TYPES } from "@/lib/businessModules/stiProtection/shared/constants"; + +const SUPPORTED_APPOINTMENT_TYPES = [ + ApiAppointmentType.HivStiConsultation, + ApiAppointmentType.ResultsReview, + ApiAppointmentType.SexWork, +] as string[]; + +export const APPOINTMENT_TYPE_OPTIONS = buildEnumOptions( + APPOINTMENT_TYPES, +).filter((option) => SUPPORTED_APPOINTMENT_TYPES.includes(option.value)); diff --git a/employee-portal/src/lib/businessModules/stiProtection/components/appointmentTypes/AppointmentTypeEditForm.tsx b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentTypes/AppointmentTypeEditForm.tsx new file mode 100644 index 0000000000000000000000000000000000000000..3ea0ab33b6566836dfa1138f84b107cf92c80e9c --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentTypes/AppointmentTypeEditForm.tsx @@ -0,0 +1,107 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiAppointmentType } from "@eshg/employee-portal-api/stiProtection"; +import { BaseField } from "@eshg/lib-portal/components/formFields/BaseField"; +import { SingleAutocompleteField } from "@eshg/lib-portal/components/formFields/autocomplete/SingleAutocompleteField"; +import { FormLabel, Input, Stack, Typography } from "@mui/joy"; +import { Formik } from "formik"; + +import { APPOINTMENT_TYPES } from "@/lib/businessModules/stiProtection/shared/constants"; +import { MultiFormButtonBar } from "@/lib/shared/components/form/MultiFormButtonBar"; +import { SidebarForm } from "@/lib/shared/components/form/SidebarForm"; +import { SidebarActions } from "@/lib/shared/components/sidebar/SidebarActions"; +import { SidebarContent } from "@/lib/shared/components/sidebar/SidebarContent"; + +export interface EditableAppointmentType { + id: string; + appointmentTypeDto: ApiAppointmentType; + standardDurationInMinutes: string; +} + +interface AppointmentTypeEditFormProps { + initialValues: EditableAppointmentType; + getSubmitButtonLabel: string; + onSubmit: (values: EditableAppointmentType) => Promise<unknown>; + onCancel: () => void; + title: string; +} + +export function AppointmentTypeEditForm( + props: Readonly<AppointmentTypeEditFormProps>, +) { + const standardDurationOptions: { + label: string; + value: string; + }[] = [ + { + value: "15", + label: "15 min", + }, + { + value: "30", + label: "30 min", + }, + { + value: "45", + label: "45 min", + }, + { + value: "60", + label: "60 min", + }, + ]; + + return ( + <Formik + initialValues={props.initialValues} + enableReinitialize={true} + onSubmit={props.onSubmit} + > + {({ initialValues, isSubmitting, handleSubmit }) => ( + <SidebarForm onSubmit={handleSubmit}> + <SidebarContent title={props.title}> + <Stack gap={2} rowGap={2}> + <BaseField> + <FormLabel> + <Typography level={"title-md"}>Typ</Typography> + </FormLabel> + <Input + placeholder={ + APPOINTMENT_TYPES[initialValues.appointmentTypeDto] + } + readOnly={true} + ></Input> + </BaseField> + <SingleAutocompleteField + label={ + <FormLabel> + <Typography level={"title-md"}> + Standarddauer (Minuten) + </Typography> + </FormLabel> + } + name="standardDurationInMinutes" + required="Bitte eine Dauer auswählen" + options={standardDurationOptions} + /> + </Stack> + </SidebarContent> + <SidebarActions> + <MultiFormButtonBar + submitLabel={props.getSubmitButtonLabel} + submitting={isSubmitting} + onCancel={() => { + props.onCancel(); + }} + /> + </SidebarActions> + </SidebarForm> + )} + </Formik> + ); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/components/appointmentTypes/AppointmentTypeOverviewTable.tsx b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentTypes/AppointmentTypeOverviewTable.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d132436340869e7d9de2bd3f59c2a0ab2b5f4a69 --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentTypes/AppointmentTypeOverviewTable.tsx @@ -0,0 +1,93 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +"use client"; + +import { ApiAppointmentTypeConfig } from "@eshg/employee-portal-api/stiProtection"; +import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; +import { FormikProps } from "formik"; +import { useRef, useState } from "react"; + +import { useUpdateAppointmentType } from "@/lib/businessModules/stiProtection/api/mutations/appointmentTypes"; +import { useGetAllAppointmentTypes } from "@/lib/businessModules/stiProtection/api/queries/appointmentTypes"; +import { + AppointmentTypeEditForm, + EditableAppointmentType, +} from "@/lib/businessModules/stiProtection/components/appointmentTypes/AppointmentTypeEditForm"; +import { appointmentTypesColumns } from "@/lib/businessModules/stiProtection/components/appointmentTypes/columns"; +import { Sidebar } from "@/lib/shared/components/sidebar/Sidebar"; +import { DataTable } from "@/lib/shared/components/table/DataTable"; +import { TableSheet } from "@/lib/shared/components/table/TableSheet"; +import { useSearchParam } from "@/lib/shared/hooks/searchParams/useSearchParam"; + +export function AppointmentTypeOverviewTable() { + const [sidebarOpenId, setSidebarOpenId] = useSearchParam("edit", "string"); + const snackbar = useSnackbar(); + + useState<ApiAppointmentTypeConfig>(); + const formikRef = useRef<FormikProps<EditableAppointmentType>>(null); + + const updateTypeMutation = useUpdateAppointmentType({ + onSuccess: () => { + snackbar.confirmation("Der Termintyp wurde aktualisiert."); + closeAndCleanSidebarForm(); + }, + }); + + const allAppointmentTypes = useGetAllAppointmentTypes(); + const currentTypeConfig = allAppointmentTypes.data.find( + (t) => t.id === sidebarOpenId, + ); + + const initialValues: EditableAppointmentType | undefined = + currentTypeConfig != null + ? { + id: currentTypeConfig.id ?? "", + appointmentTypeDto: currentTypeConfig.appointmentTypeDto, + standardDurationInMinutes: + currentTypeConfig.standardDurationInMinutes?.toString() ?? "", + } + : undefined; + + function editEntry(typeConfig: ApiAppointmentTypeConfig) { + setSidebarOpenId(typeConfig.id); + } + + function doSubmit(values: EditableAppointmentType) { + const standardDurationInMinutes = parseInt( + values.standardDurationInMinutes, + 10, + ); + const request = { standardDurationInMinutes: standardDurationInMinutes }; + return updateTypeMutation.mutateAsync({ id: values.id, request }); + } + + function closeAndCleanSidebarForm() { + setSidebarOpenId(null); + formikRef.current?.resetForm(); + } + + return ( + <> + <TableSheet> + <DataTable + data={allAppointmentTypes.data} + columns={appointmentTypesColumns(editEntry)} + /> + </TableSheet> + <Sidebar open={initialValues != null} onClose={closeAndCleanSidebarForm}> + {initialValues != null ? ( + <AppointmentTypeEditForm + initialValues={initialValues} + getSubmitButtonLabel={"Speichern"} + onSubmit={doSubmit} + onCancel={closeAndCleanSidebarForm} + title={"Terminart bearbeiten"} + /> + ) : null} + </Sidebar> + </> + ); +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/components/appointmentTypes/columns.tsx b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentTypes/columns.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e9835b2c6fb65c96f50b021c14cec024c569831b --- /dev/null +++ b/employee-portal/src/lib/businessModules/stiProtection/components/appointmentTypes/columns.tsx @@ -0,0 +1,45 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { ApiAppointmentTypeConfig } from "@eshg/employee-portal-api/stiProtection"; +import { Edit } from "@mui/icons-material"; +import { ColumnHelper, createColumnHelper } from "@tanstack/react-table"; + +import { APPOINTMENT_TYPES } from "@/lib/businessModules/stiProtection/shared/constants"; +import { ActionsMenu } from "@/lib/shared/components/buttons/ActionsMenu"; + +const columnHelper: ColumnHelper<ApiAppointmentTypeConfig> = + createColumnHelper<ApiAppointmentTypeConfig>(); + +export function appointmentTypesColumns( + editEntry: (type: ApiAppointmentTypeConfig) => void, +) { + return [ + columnHelper.accessor("appointmentTypeDto", { + header: "Termintyp", + cell: (props) => APPOINTMENT_TYPES[props.getValue()], + }), + columnHelper.accessor("standardDurationInMinutes", { + header: "Standard-Termindauer", + }), + columnHelper.display({ + header: "Aktionen", + cell: (info) => ( + <ActionsMenu + actionItems={[ + { + label: "Bearbeiten", + onClick: () => editEntry(info.row.original), + startDecorator: <Edit />, + }, + ]} + /> + ), + meta: { + width: 96, + }, + }), + ]; +} diff --git a/employee-portal/src/lib/businessModules/stiProtection/procedures/addNewProcedure/PersonalDataForm.tsx b/employee-portal/src/lib/businessModules/stiProtection/procedures/addNewProcedure/PersonalDataForm.tsx index 492ff3744c2dc01297d5b6f86c610b3cc40b87b4..988f137c337f98f62d1daee13bba4c3a3c9503fe 100644 --- a/employee-portal/src/lib/businessModules/stiProtection/procedures/addNewProcedure/PersonalDataForm.tsx +++ b/employee-portal/src/lib/businessModules/stiProtection/procedures/addNewProcedure/PersonalDataForm.tsx @@ -17,7 +17,7 @@ const thisYear = new Date().getFullYear(); const validateYear = createBoundedIntValidator( thisYear - 150, thisYear, - "Bitte eine Jahre angeben.", + "Bitte ein gültiges Jahr eingeben.", ); export function PersonalDataForm() { @@ -27,12 +27,12 @@ export function PersonalDataForm() { name="gender" label="Geschlecht" options={GENDER_OPTIONS} - required="Bitte ein Geschlecht auswählen" + required="Bitte ein Geschlecht auswählen." /> <NumberField name="yearOfBirth" label="Geburtsjahr" - required="Bitte eingeben" + required="Bitte ein gültiges Jahr eingeben." validate={validateYear} /> <SingleAutocompleteField diff --git a/employee-portal/src/lib/businessModules/stiProtection/shared/constants.ts b/employee-portal/src/lib/businessModules/stiProtection/shared/constants.ts index 58400b2aee4c9c216bf663c5614de91e141aab21..76c3e137864be6e308240815ead2485f9bfac025 100644 --- a/employee-portal/src/lib/businessModules/stiProtection/shared/constants.ts +++ b/employee-portal/src/lib/businessModules/stiProtection/shared/constants.ts @@ -13,6 +13,10 @@ import { } from "@eshg/employee-portal-api/stiProtection"; import { EnumMap } from "@eshg/lib-portal/types/helpers"; +export const procedureTypes = [ApiProcedureType.StiProtection]; + +export const taskTypes = [ApiTaskType.StiProtection]; + export const PROCEDURE_STATUS_VALUES: EnumMap<ApiProcedureStatus> = { [ApiProcedureStatus.Aborted]: "Abgebrochen", [ApiProcedureStatus.Closed]: "Geschlossen", @@ -42,14 +46,14 @@ export const GENDER_VALUES: EnumMap<ApiGender> = { }; export const APPOINTMENT_TYPES: EnumMap<ApiAppointmentType> = { - [ApiAppointmentType.RegularExamination]: "Regeluntersuchung", [ApiAppointmentType.CanChild]: "Kann-Kinder", - [ApiAppointmentType.EntryLevel]: "Eingangsstufe", - [ApiAppointmentType.SpecialNeeds]: "Besonderer Förderbedarf", [ApiAppointmentType.Consultation]: "Beratung", - [ApiAppointmentType.Vaccination]: "Impfung", + [ApiAppointmentType.EntryLevel]: "Eingangsstufe", [ApiAppointmentType.ProofSubmission]: "Nachweisvorlage", [ApiAppointmentType.HivStiConsultation]: "HIV-STI-Beratung", [ApiAppointmentType.SexWork]: "Sexarbeit", [ApiAppointmentType.ResultsReview]: "Ergebnisbesprechung", + [ApiAppointmentType.RegularExamination]: "Regeluntersuchung", + [ApiAppointmentType.SpecialNeeds]: "Besonderer Förderbedarf", + [ApiAppointmentType.Vaccination]: "Impfung", }; diff --git a/employee-portal/src/lib/businessModules/stiProtection/shared/routes.ts b/employee-portal/src/lib/businessModules/stiProtection/shared/routes.ts index 4f7abd75cf3a30f7ac5b28a609bf7f7c95da92a1..f284e5826e3a56df7671e7ef1826a433084f05fb 100644 --- a/employee-portal/src/lib/businessModules/stiProtection/shared/routes.ts +++ b/employee-portal/src/lib/businessModules/stiProtection/shared/routes.ts @@ -8,6 +8,7 @@ const proceduresPath = `${basePath}/procedures`; const appointmentBlockPath = `${basePath}/appointment-block-groups`; export const routes = { + appointmentDefinition: `${basePath}/appointment-definition`, procedures: { index: `${proceduresPath}`, byId: (procedureId: string) => ({ diff --git a/employee-portal/src/lib/businessModules/stiProtection/shared/sideNavigationItem.tsx b/employee-portal/src/lib/businessModules/stiProtection/shared/sideNavigationItem.tsx index 7874787d343400d26430d866dd52bfa9071fc80e..25dbbd463baecac6491fcf7c9636ae9142d13ca9 100644 --- a/employee-portal/src/lib/businessModules/stiProtection/shared/sideNavigationItem.tsx +++ b/employee-portal/src/lib/businessModules/stiProtection/shared/sideNavigationItem.tsx @@ -29,7 +29,12 @@ const defaultSubItems: SideNavigationSubItem[] = [ { name: "Terminblöcke", href: routes.appointmentBlockGroups.index, - accessCheck: hasUserRole(ApiUserRole.StiProtectionAdmin), + accessCheck: hasUserRole(ApiUserRole.StiProtectionUser), + }, + { + name: "Terminarten", + href: routes.appointmentDefinition, + accessCheck: hasUserRole(ApiUserRole.StiProtectionUser), }, ]; diff --git a/employee-portal/src/lib/businessModules/travelMedicine/api/clients.ts b/employee-portal/src/lib/businessModules/travelMedicine/api/clients.ts index 89c78eea7898b3f856112ea0b7ac188534049c4e..34ba2585a4308cd7ee4349edbe5d9a60f89e362b 100644 --- a/employee-portal/src/lib/businessModules/travelMedicine/api/clients.ts +++ b/employee-portal/src/lib/businessModules/travelMedicine/api/clients.ts @@ -7,6 +7,7 @@ import { AppointmentBlockApi, AppointmentTypeApi, ApprovalRequestApi, + ArchivingApi, Configuration, DiseaseApi, EditorApi, @@ -111,3 +112,8 @@ export function useEditorApi() { export function useTextBlockApi() { return new TextBlockApi(useConfiguration()); } + +export function useArchivingApi() { + const configuration = useConfiguration(); + return new ArchivingApi(configuration); +} diff --git a/employee-portal/src/lib/businessModules/travelMedicine/api/mutations/archiving.ts b/employee-portal/src/lib/businessModules/travelMedicine/api/mutations/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..0fa2e16eb5114ac06eb1b3c7b3a8782f10b52708 --- /dev/null +++ b/employee-portal/src/lib/businessModules/travelMedicine/api/mutations/archiving.ts @@ -0,0 +1,18 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useArchivingApi } from "@/lib/businessModules/travelMedicine/api/clients"; +import { + useBulkUpdateProceduresArchivingRelevanceTemplate, + useExportRelevantProceduresTemplate, +} from "@/lib/shared/api/mutations/archiving"; + +export function useBulkUpdateProceduresArchivingRelevance() { + return useBulkUpdateProceduresArchivingRelevanceTemplate(useArchivingApi); +} + +export function useExportRelevantProcedures() { + return useExportRelevantProceduresTemplate(useArchivingApi); +} diff --git a/employee-portal/src/lib/businessModules/travelMedicine/api/queries/archiving.ts b/employee-portal/src/lib/businessModules/travelMedicine/api/queries/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..495d3802c5d1832025a53e15385ec8396041f00f --- /dev/null +++ b/employee-portal/src/lib/businessModules/travelMedicine/api/queries/archiving.ts @@ -0,0 +1,44 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + GetArchivableProceduresRequest, + GetRelevantArchivableProceduresRequest, +} from "@eshg/employee-portal-api/businessProcedures"; + +import { useArchivingApi } from "@/lib/businessModules/travelMedicine/api/clients"; +import { archivingApiQueryKey } from "@/lib/businessModules/travelMedicine/api/queries/queryKeys"; +import { + useGetArchivableProceduresTemplate, + useGetArchivingConfigurationTemplate, + useGetRelevantArchivableProceduresTemplate, +} from "@/lib/shared/api/queries/archiving"; + +export function useGetArchivingConfiguration() { + return useGetArchivingConfigurationTemplate( + useArchivingApi, + archivingApiQueryKey, + ); +} + +export function useGetArchivableProcedures( + request: GetArchivableProceduresRequest, +) { + return useGetArchivableProceduresTemplate( + useArchivingApi, + archivingApiQueryKey, + request, + ); +} + +export function useGetRelevantArchivableProcedures( + request: GetRelevantArchivableProceduresRequest, +) { + return useGetRelevantArchivableProceduresTemplate( + useArchivingApi, + archivingApiQueryKey, + request, + ); +} diff --git a/employee-portal/src/lib/businessModules/travelMedicine/api/queries/queryKeys.ts b/employee-portal/src/lib/businessModules/travelMedicine/api/queries/queryKeys.ts index 548598264869d25c585a8497d4614a87b45e67a0..c4199c1d07b2a3ee84fd071869294cf25c908b72 100644 --- a/employee-portal/src/lib/businessModules/travelMedicine/api/queries/queryKeys.ts +++ b/employee-portal/src/lib/businessModules/travelMedicine/api/queries/queryKeys.ts @@ -66,3 +66,7 @@ export const travelMedicineFeatureTogglesPublicApiQueryKey = queryKeyFactory( ); export const editorApiQueryKey = queryKeyFactory(apiQueryKey(["editorApi"])); + +export const archivingApiQueryKey = queryKeyFactory( + apiQueryKey(["archivingApi"]), +); diff --git a/employee-portal/src/lib/businessModules/travelMedicine/components/appointmentBlocks/appointmentBlocksGroupForm/AppointmentBlockGroupForm.tsx b/employee-portal/src/lib/businessModules/travelMedicine/components/appointmentBlocks/appointmentBlocksGroupForm/AppointmentBlockGroupForm.tsx index bf4af7713ce46ccf804caef83fd4008d40b75045..d21762d4aca76663c3d6d10ff1e5c951492b7bc0 100644 --- a/employee-portal/src/lib/businessModules/travelMedicine/components/appointmentBlocks/appointmentBlocksGroupForm/AppointmentBlockGroupForm.tsx +++ b/employee-portal/src/lib/businessModules/travelMedicine/components/appointmentBlocks/appointmentBlocksGroupForm/AppointmentBlockGroupForm.tsx @@ -5,6 +5,7 @@ import { ApiUser } from "@eshg/employee-portal-api/base"; import { ApiAppointmentType } from "@eshg/employee-portal-api/travelMedicine"; +import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; import { OptionalFieldValue } from "@eshg/lib-portal/types/form"; import { Divider, Stack } from "@mui/joy"; import { Formik, FormikErrors } from "formik"; @@ -14,7 +15,10 @@ import { APPOINTMENT_TYPE_OPTIONS } from "@/lib/businessModules/travelMedicine/c import { routes } from "@/lib/businessModules/travelMedicine/shared/routes"; import { AppointmentBlockGroupValuesWithDays } from "@/lib/shared/components/appointmentBlocks/AppointmentBlockFormWithDays"; import { AppointmentBlockGroupFields } from "@/lib/shared/components/appointmentBlocks/AppointmentBlockGroupFields"; -import { AppointmentCountWithDays } from "@/lib/shared/components/appointmentBlocks/AppointmentCountWithDays"; +import { + AppointmentCountWithDays, + calculateAppointmentCount, +} from "@/lib/shared/components/appointmentBlocks/AppointmentCountWithDays"; import { AppointmentStaffSelection } from "@/lib/shared/components/appointmentBlocks/AppointmentStaffSelection"; import { FormButtonBar } from "@/lib/shared/components/form/FormButtonBar"; import { FormSheet } from "@/lib/shared/components/form/FormSheet"; @@ -48,6 +52,18 @@ function validateForm(values: AppointmentBlockGroupValues) { return errors; } +function hasAtLeastOneAppointmentInGroup(values: AppointmentBlockGroupValues) { + return ( + calculateAppointmentCount({ + ...values, + appointmentDurations: values.allAppointmentTypes, + parallelExaminations: (values.parallelExaminations as number) ?? 1, + skipCalculatingOfBlocks: + validateForm(values).appointmentBlocks != undefined, + }) > 0 + ); +} + interface AppointmentBlockGroupFormProps { initialValues: AppointmentBlockGroupValues; onSubmit: (values: AppointmentBlockGroupValues) => Promise<void>; @@ -70,6 +86,7 @@ export interface AppointmentBlockGroupValues { export function AppointmentBlockGroupForm( props: Readonly<AppointmentBlockGroupFormProps>, ) { + const snackbar = useSnackbar(); const physicianOptions = props.allPhysicians.map((option) => ({ value: option.userId, label: fullName(option), @@ -83,7 +100,15 @@ export function AppointmentBlockGroupForm( return ( <Formik initialValues={props.initialValues} - onSubmit={props.onSubmit} + onSubmit={async (appointments) => { + if (hasAtLeastOneAppointmentInGroup(appointments)) { + await props.onSubmit(appointments); + } else { + snackbar.notification( + "Es muss mindestens ein Termin enthalten sein.", + ); + } + }} validate={validateForm} > {({ values, isSubmitting, handleSubmit }) => ( @@ -100,7 +125,7 @@ export function AppointmentBlockGroupForm( <Stack gap={4}> <AppointmentStaffSelection physicianOptions={physicianOptions} - medicalAssistantsOptions={medicalAssistantsOptions} + medicalAssistantOptions={medicalAssistantsOptions} freeStaff={props.freeStaff} blockedStaff={props.blockedStaff} validateAvailability={() => props.validateAvailability(values)} diff --git a/employee-portal/src/lib/businessModules/travelMedicine/components/appointmentBlocks/appointmentBlocksGroupForm/validateAppointmentBlock.ts b/employee-portal/src/lib/businessModules/travelMedicine/components/appointmentBlocks/appointmentBlocksGroupForm/validateAppointmentBlock.ts index 7da276d088d6b7ab7e498aa3eaee754bff14d186..514ec4ecaa3d9bf33d4cfd20b6a60483f4e4f6da 100644 --- a/employee-portal/src/lib/businessModules/travelMedicine/components/appointmentBlocks/appointmentBlocksGroupForm/validateAppointmentBlock.ts +++ b/employee-portal/src/lib/businessModules/travelMedicine/components/appointmentBlocks/appointmentBlocksGroupForm/validateAppointmentBlock.ts @@ -10,7 +10,7 @@ import { differenceInCalendarDays, isBefore, isEqual, isPast } from "date-fns"; import { FormikErrors } from "formik"; import { isEmpty } from "remeda"; -import { getAppointmentDurationInMinutes } from "@/lib/businessModules/measlesProtection/shared/helper"; +import { getAppointmentDurationInMinutes } from "@/lib/businessModules/measlesProtection/shared/helpers"; import { AppointmentBlockGroupValuesWithDays } from "@/lib/shared/components/appointmentBlocks/AppointmentBlockFormWithDays"; import { calculateAppointmentsPerBlock } from "@/lib/shared/components/appointmentBlocks/AppointmentCountWithDays"; import { toLocalDateTime } from "@/lib/shared/helpers/dateTime"; diff --git a/employee-portal/src/lib/businessModules/travelMedicine/components/vaccinationConsultationSearch/VaccinationConsultationsSearchTable.tsx b/employee-portal/src/lib/businessModules/travelMedicine/components/vaccinationConsultationSearch/VaccinationConsultationsSearchTable.tsx index 1af7fb1c1d74625e1cb65ac0dc736d09b458d876..dad92d9230f46809f6ae6ef401bebf6b1239706a 100644 --- a/employee-portal/src/lib/businessModules/travelMedicine/components/vaccinationConsultationSearch/VaccinationConsultationsSearchTable.tsx +++ b/employee-portal/src/lib/businessModules/travelMedicine/components/vaccinationConsultationSearch/VaccinationConsultationsSearchTable.tsx @@ -62,17 +62,11 @@ export function VaccinationConsultationsSearchTable() { controls={ <ButtonBar left={ - <> - <FilterButton - isFilterVisible={filterVisible} - activeFilters={activeFilters.length} - onClick={toggleFilterVisible} - /> - <Alert - title="Es werden maximal 50 Suchergebnisse angezeigt." - color="primary" - /> - </> + <FilterButton + isFilterVisible={filterVisible} + activeFilters={activeFilters.length} + onClick={toggleFilterVisible} + /> } /> } @@ -89,7 +83,15 @@ export function VaccinationConsultationsSearchTable() { ) } > - <TableSheet loading={searchResults.isFetching}> + <TableSheet + loading={searchResults.isFetching} + title={ + <Alert + title="Es werden maximal 50 Suchergebnisse angezeigt." + color="primary" + /> + } + > <DataTable data={ filterValuesNotEmpty() diff --git a/employee-portal/src/lib/businessModules/travelMedicine/shared/routes.ts b/employee-portal/src/lib/businessModules/travelMedicine/shared/routes.ts index 48a44e0a6f84dfac5c12139eaf23952b8183e201..ff899758d39e61b29895613346c6013a482f9fbe 100644 --- a/employee-portal/src/lib/businessModules/travelMedicine/shared/routes.ts +++ b/employee-portal/src/lib/businessModules/travelMedicine/shared/routes.ts @@ -3,8 +3,6 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { ApiAppointmentType } from "@eshg/employee-portal-api/travelMedicine"; - const basePath = "/travel-medicine"; const informationStatementTemplatesPath = `${basePath}/information-statement-templates`; const medicalHistoryTemplatesPath = `${basePath}/medical-history-templates`; @@ -33,8 +31,6 @@ export const routes = { }, procedures: { index: `${proceduresPath}`, - new: `${proceduresPath}/new`, - details: (procedureId: string) => `${proceduresPath}/${procedureId}`, baseData: (procedureId: string) => `${proceduresPath}/${procedureId}/base-data`, medicalHistories: (procedureId: string, procedureStepId?: string) => @@ -46,24 +42,10 @@ export const routes = { downloadFile: (fileId: string) => `${proceduresPath}/download-file/${fileId}`, progressEntries: (procedureId: string) => ({ - index: `${routes.procedures.details(procedureId)}/progress-entries`, + index: `${proceduresPath}/${procedureId}/progress-entries`, details: (entryId: string) => - `${routes.procedures.progressEntries(procedureId).index}/${entryId}/details`, + `${proceduresPath}/${procedureId}/progress-entries/${entryId}/details`, }), - bookAppointment: ( - procedureId: string, - stepId: string, - appointmentType: ApiAppointmentType, - ) => - `${routes.procedures.details(procedureId)}/${stepId}/${appointmentType}/book-appointment`, - vaccinations: (id: string, stepId: string) => - `${routes.procedures.details(id)}/procedure-step/${stepId}/vaccinations`, - otherServices: (id: string, stepId: string) => - `${routes.procedures.details(id)}/procedure-step/${stepId}/other-services`, - medicalHistory: { - details: (medicalHistoryId: string) => - `${proceduresPath}/medical-history/${medicalHistoryId}`, - }, }, proceduresSearch: { index: `${proceduresSearchPath}` }, appointmentTypes: { @@ -78,8 +60,6 @@ export const routes = { appointmentBlockGroups: { index: `${appointmentBlockPath}`, new: `${appointmentBlockPath}/new`, - details: (appointmentId: string) => - `${appointmentBlockPath}/${appointmentId}`, }, otherServiceTemplates: { index: `${otherServicesTemplatesPath}`, diff --git a/employee-portal/src/lib/shared/api/mutations/archiving.ts b/employee-portal/src/lib/shared/api/mutations/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..ca56074baaaaf395c2b796f45405defe825216f0 --- /dev/null +++ b/employee-portal/src/lib/shared/api/mutations/archiving.ts @@ -0,0 +1,107 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + ApiArchivingRelevance, + ArchivingApi, +} from "@eshg/employee-portal-api/businessProcedures"; +import { useHandledMutation } from "@eshg/lib-portal/api/useHandledMutation"; +import { useSnackbar } from "@eshg/lib-portal/components/snackbar/SnackbarProvider"; + +import { join } from "@/lib/shared/helpers/strings"; + +type UseBulkUpdateProceduresArchivingRelevanceResult = ReturnType< + typeof useBulkUpdateProceduresArchivingRelevanceTemplate +>; +export type UseBulkUpdateProceduresArchivingRelevance = + () => UseBulkUpdateProceduresArchivingRelevanceResult; + +export function useBulkUpdateProceduresArchivingRelevanceTemplate( + useArchivingApi: () => Pick< + ArchivingApi, + "bulkUpdateProceduresArchivingRelevance" + >, +) { + const snackbar = useSnackbar(); + const archiving = useArchivingApi(); + + return useHandledMutation({ + mutationFn: async ({ + procedureIds, + archivingRelevance, + }: { + procedureIds: string[]; + archivingRelevance: ApiArchivingRelevance; + }) => + archiving.bulkUpdateProceduresArchivingRelevance({ + procedures: new Set(procedureIds), + archivingRelevance, + }), + onSuccess: (data) => { + const { updatedProcedures, failedProcedures, archivingRelevance } = data; + const updatedProceduresCount = Array.from(updatedProcedures).length; + const failedProceduresCount = Array.from(failedProcedures).length; + const text = buildSnackbarText( + archivingRelevance === ApiArchivingRelevance.Relevant + ? "archiviert" + : "gelöscht", + updatedProceduresCount, + failedProceduresCount, + ); + if (failedProceduresCount > 0) { + snackbar.error(text); + } else { + snackbar.confirmation(text); + } + }, + }); +} + +function buildSnackbarText( + verb: string, + updatedProceduresCount: number, + failedProceduresCount: number, +) { + const successfulUpdatesText = + updatedProceduresCount === 1 + ? `1 Vorgang wurde ${verb}.` + : `${updatedProceduresCount} Vorgänge wurden ${verb}.`; + + if (failedProceduresCount === 0) { + return successfulUpdatesText; + } + + const failedUpdatesText = + failedProceduresCount === 1 + ? `1 ausgewählter Vorgang konnte nicht ${verb} werden.` + : `${failedProceduresCount} ausgewählte Vorgänge konnten nicht ${verb} werden.`; + + return join([successfulUpdatesText, failedUpdatesText], " "); +} + +type UseExportRelevantProceduresResult = ReturnType< + typeof useExportRelevantProceduresTemplate +>; +export type UseExportRelevantProcedures = + () => UseExportRelevantProceduresResult; + +export function useExportRelevantProceduresTemplate( + useArchivingApi: () => Pick<ArchivingApi, "exportRelevantProceduresRaw">, +) { + const snackbar = useSnackbar(); + const archiving = useArchivingApi(); + + return useHandledMutation({ + mutationFn: async ({ procedureIds }: { procedureIds: string[] }) => + archiving.exportRelevantProceduresRaw({ + apiExportArchivingRelevantProceduresRequest: { + procedures: new Set(procedureIds), + }, + }), + onSuccess: () => { + snackbar.confirmation("Vorgänge wurden exportiert."); + }, + }); +} diff --git a/employee-portal/src/lib/shared/api/queries/archiving.ts b/employee-portal/src/lib/shared/api/queries/archiving.ts new file mode 100644 index 0000000000000000000000000000000000000000..b217411280f91e03e2f8d40755e53b34ff6992d5 --- /dev/null +++ b/employee-portal/src/lib/shared/api/queries/archiving.ts @@ -0,0 +1,89 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + ArchivingApi, + GetArchivableProceduresRequest, + GetRelevantArchivableProceduresRequest, +} from "@eshg/employee-portal-api/businessProcedures"; +import { type QueryKeyFactory } from "@eshg/lib-portal/api/queryKeyFactory"; +import { unwrapRawResponse } from "@eshg/lib-portal/api/unwrapRawResponse"; +import { useSuspenseQuery } from "@tanstack/react-query"; + +import { mapArchivableProceduresResponse } from "@/lib/shared/components/archiving/api/models/archivableProcedure"; + +type UseGetArchivingConfigurationResult = ReturnType< + typeof useGetArchivingConfigurationTemplate +>; +export type UseGetArchivingConfiguration = + () => UseGetArchivingConfigurationResult; + +export function useGetArchivingConfigurationTemplate( + useArchivingApi: () => Pick<ArchivingApi, "getArchivingConfiguration">, + queryKeyFactory: QueryKeyFactory, +) { + const archivingApi = useArchivingApi(); + + return useSuspenseQuery({ + queryKey: queryKeyFactory(["getArchivingConfiguration"]), + queryFn: () => archivingApi.getArchivingConfiguration(), + staleTime: 60_000, + }); +} + +type UseGetArchivableProceduresResult = ReturnType< + typeof useGetArchivableProceduresTemplate +>; +export type UseGetArchivableProcedures = ( + request: GetArchivableProceduresRequest, +) => UseGetArchivableProceduresResult; + +export function useGetArchivableProceduresTemplate( + useArchivingApi: () => Pick<ArchivingApi, "getArchivableProceduresRaw">, + queryKeyFactory: QueryKeyFactory, + request: GetArchivableProceduresRequest, +) { + const archivingApi = useArchivingApi(); + + return useSuspenseQuery({ + queryKey: queryKeyFactory([ + "getArchivableProcedures", + request, + Array.from(request.defaultArchivingRelevance ?? []), + Array.from(request.procedureType ?? []), + ]), + queryFn: () => + archivingApi + .getArchivableProceduresRaw(request) + .then(unwrapRawResponse) + .then(mapArchivableProceduresResponse), + }); +} + +type UseGetRelevantArchivableProceduresResult = ReturnType< + typeof useGetRelevantArchivableProceduresTemplate +>; +export type UseGetRelevantArchivableProcedures = ( + request: GetRelevantArchivableProceduresRequest, +) => UseGetRelevantArchivableProceduresResult; + +export function useGetRelevantArchivableProceduresTemplate( + useArchivingApi: () => Pick< + ArchivingApi, + "getRelevantArchivableProceduresRaw" + >, + queryKeyFactory: QueryKeyFactory, + request: GetRelevantArchivableProceduresRequest, +) { + const archivingApi = useArchivingApi(); + + return useSuspenseQuery({ + queryKey: queryKeyFactory(["getRelevantArchivableProceduresRaw", request]), + queryFn: () => + archivingApi + .getRelevantArchivableProceduresRaw(request) + .then(unwrapRawResponse), + }); +} diff --git a/employee-portal/src/lib/shared/api/queries/tasks.ts b/employee-portal/src/lib/shared/api/queries/tasks.ts index 0d392dd46d2f2d98b1d3e308e759735a6fba265d..5f039a1af5a2a6d7fe3fdf7bd384ef0eb3d1b9b6 100644 --- a/employee-portal/src/lib/shared/api/queries/tasks.ts +++ b/employee-portal/src/lib/shared/api/queries/tasks.ts @@ -9,29 +9,36 @@ import { GetTasksByAssigneeRequest, } from "@eshg/employee-portal-api/businessProcedures"; import { unwrapRawResponse } from "@eshg/lib-portal/api/unwrapRawResponse"; -import { useSuspenseQuery } from "@tanstack/react-query"; +import { queryOptions } from "@tanstack/react-query"; import { useSearchParams } from "next/navigation"; export interface TeamviewFilters { assigneeId?: Set<string>; } -export function useFetchTasksForTeamViewTemplate( +interface UseFetchTasksForTeamViewTemplateProps { useTaskApi: () => { getTasksByAssigneeRaw: ( request: GetTasksByAssigneeRequest, initOverrides?: RequestInit, ) => Promise<ApiResponse<ApiGetTaskByUserResponse>>; - }, + }; queryKeyFactory: ( queryKey: (string | Record<string, string> | string[])[], - ) => readonly (string | Record<string, string> | string[])[], - teamviewFilters: TeamviewFilters, - getInitOverrides?: () => RequestInit, -) { + ) => readonly (string | Record<string, string> | string[])[]; + teamviewFilters: TeamviewFilters; + getInitOverrides?: () => RequestInit; +} + +export function useFetchTasksForTeamViewTemplateOptions({ + useTaskApi, + queryKeyFactory, + teamviewFilters, + getInitOverrides, +}: UseFetchTasksForTeamViewTemplateProps) { const taskApi = useTaskApi(); const searchParams = Object.fromEntries(useSearchParams().entries()); - return useSuspenseQuery({ + return queryOptions({ queryKey: queryKeyFactory([ "fetchTasks", searchParams, diff --git a/employee-portal/src/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper.tsx b/employee-portal/src/lib/shared/components/SidebarStepper/SidebarStepper.tsx similarity index 82% rename from employee-portal/src/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper.tsx rename to employee-portal/src/lib/shared/components/SidebarStepper/SidebarStepper.tsx index 54dff4783f18e0e704751e520d707695c574ee37..12d6028eddf0dbd05f48598bb5d19d8b943f21ff 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/shared/SidebarStepper/SidebarStepper.tsx +++ b/employee-portal/src/lib/shared/components/SidebarStepper/SidebarStepper.tsx @@ -1,16 +1,16 @@ /** * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only + * SPDX-License-Identifier: Apache-2.0 */ import { SubmitButton } from "@eshg/lib-portal/components/buttons/SubmitButton"; import { useAlertContext } from "@eshg/lib-portal/errorHandling/AlertContext"; import { Button, DialogTitle, Stack, Typography, ZIndex } from "@mui/joy"; -import { Formik, FormikErrors, FormikValues } from "formik"; -import { useState } from "react"; +import { Formik, FormikErrors, FormikProps, FormikValues } from "formik"; +import { useEffect, useRef, useState } from "react"; import { isBoolean } from "remeda"; -import { SidebarStep } from "@/lib/businessModules/statistics/components/shared/SidebarStepper/sidebarStep"; +import { SidebarStep } from "@/lib/shared/components/SidebarStepper/sidebarStep"; import { SidebarForm } from "@/lib/shared/components/form/SidebarForm"; import { Sidebar } from "@/lib/shared/components/sidebar/Sidebar"; import { SidebarActions } from "@/lib/shared/components/sidebar/SidebarActions"; @@ -41,6 +41,7 @@ export function SidebarStepper<T extends FormikValues>({ onClose: onClose, }); const alertContext = useAlertContext(); + const formikRef = useRef<FormikProps<T>>(null); const currentStep = steps[stepIndex]!; @@ -100,9 +101,16 @@ export function SidebarStepper<T extends FormikValues>({ alertContext?.setAlert(null); } + useEffect(() => { + if (open) { + formikRef.current?.resetForm(); + } + }, [open]); + return ( <Sidebar open={open} onClose={handleClose} zIndex={zIndex}> <Formik + innerRef={formikRef} initialValues={initialValues} onSubmit={onSubmit} validate={(model) => { @@ -141,29 +149,27 @@ export function SidebarStepper<T extends FormikValues>({ const isDisabledNextStep = stepIndex >= steps.length - 1 || continueOrSubmitIsDisabled; return ( - <> - <SidebarForm ref={sidebarFormRef}> - <SidebarContent - header={ - <Stack gap={0.5}> - <DialogTitle - sx={{ color: "text.primary" }} - level="h3" - component="h1" - > - {currentStepProps.title} - </DialogTitle> - {steps.length > 1 && ( - <Typography level="title-md" textColor="text.secondary"> - Schritt {stepIndex + 1} von {steps.length} - </Typography> - )} - </Stack> - } - > - {currentStepProps.content} - </SidebarContent> - </SidebarForm> + <SidebarForm ref={sidebarFormRef}> + <SidebarContent + header={ + <Stack gap={0.5}> + <DialogTitle + sx={{ color: "text.primary" }} + level="h3" + component="h1" + > + {currentStepProps.title} + </DialogTitle> + {steps.length > 1 && ( + <Typography level="title-md" textColor="text.secondary"> + Schritt {stepIndex + 1} von {steps.length} + </Typography> + )} + </Stack> + } + > + {currentStepProps.content} + </SidebarContent> <SidebarActions> <Stack direction="row" justifyContent="space-between"> <Stack direction="row"> @@ -206,7 +212,7 @@ export function SidebarStepper<T extends FormikValues>({ </Stack> </Stack> </SidebarActions> - </> + </SidebarForm> ); }} </Formik> diff --git a/employee-portal/src/lib/businessModules/statistics/components/shared/SidebarStepper/sidebarStep.ts b/employee-portal/src/lib/shared/components/SidebarStepper/sidebarStep.ts similarity index 93% rename from employee-portal/src/lib/businessModules/statistics/components/shared/SidebarStepper/sidebarStep.ts rename to employee-portal/src/lib/shared/components/SidebarStepper/sidebarStep.ts index f1a865388e8baa2751a4c66e0d2042494cbe66ec..08bf15ee90be405f75662071015a728b07d7fea0 100644 --- a/employee-portal/src/lib/businessModules/statistics/components/shared/SidebarStepper/sidebarStep.ts +++ b/employee-portal/src/lib/shared/components/SidebarStepper/sidebarStep.ts @@ -1,6 +1,6 @@ /** * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only + * SPDX-License-Identifier: Apache-2.0 */ import { FormikErrors } from "formik"; diff --git a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockFieldArrayWithDays.tsx b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockFieldArrayWithDays.tsx index 978427eeb6a3da50ca70dae9d1191c4df986bab9..eaa708cc2695f82c41b15397635c9917c87f0654 100644 --- a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockFieldArrayWithDays.tsx +++ b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockFieldArrayWithDays.tsx @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Add, DeleteOutlined } from "@mui/icons-material"; +import { Add, Delete } from "@mui/icons-material"; import { Grid } from "@mui/joy"; import { FieldArray } from "formik"; @@ -54,8 +54,9 @@ export function AppointmentBlockFieldArrayWithDays( <FieldIconButton title="Terminblock entfernen" onClick={() => remove(index)} + color="danger" > - <DeleteOutlined /> + <Delete color="danger" /> </FieldIconButton> )} </FieldButtonBar> diff --git a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockFormWithDays.tsx b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockFormWithDays.tsx index d7c3423bf76c4982a76113670edd1191f9a41dbe..856bb19964e794db2083766126f7eea60b30fa7a 100644 --- a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockFormWithDays.tsx +++ b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockFormWithDays.tsx @@ -104,7 +104,7 @@ export function AppointmentBlockFormWithDays(props: Readonly<NestedFormProps>) { <Grid direction={"column"}> <WeekdayCheckboxGroup name={fieldName("daysOfWeek")} - element={daysOfWeekOptions} + options={daysOfWeekOptions} label={"Wochentage"} sx={{ mt: 1 }} /> diff --git a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockGroupFields.tsx b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockGroupFields.tsx index a6934fee356e87179b8c5eeed96d589a0bfad9e2..772941942d62cf5b7847d957bb08e46e2f3d421b 100644 --- a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockGroupFields.tsx +++ b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentBlockGroupFields.tsx @@ -28,7 +28,7 @@ export interface AppointmentBlockGroupFieldsProps { appointmentBlocks?: AppointmentBlockValues[]; appointmentBlocksWithDays?: AppointmentBlockGroupValuesWithDays[]; options: SelectOption[]; - showParallelExaminations: boolean; + showParallelExaminations?: boolean; showAppointmentBlockFieldArrayWithDays: boolean; } diff --git a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentCountWithDays.tsx b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentCountWithDays.tsx index 9583b59e09ba45902d6167001b6d6633bd7555d8..9d129d185e4eddb548f677bdc87c19af79a58407 100644 --- a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentCountWithDays.tsx +++ b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentCountWithDays.tsx @@ -14,7 +14,7 @@ import { Chip, Stack, Typography } from "@mui/joy"; import { eachDayOfInterval, intervalToDuration } from "date-fns"; import { AppointmentBlockGroupValues } from "@/lib/businessModules/measlesProtection/components/appointmentBlocks/AppointmentBlockGroupForm"; -import { getAppointmentDurationInMinutes } from "@/lib/businessModules/measlesProtection/shared/helper"; +import { getAppointmentDurationInMinutes } from "@/lib/businessModules/measlesProtection/shared/helpers"; import { AppointmentBlockGroupValuesWithDays, WEEKDAY_CHECKBOX_OPTIONS, diff --git a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentStaffField.tsx b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentStaffField.tsx index f211bbb13f4296f7fc7637616479fb54cf261c51..167afdc68e4be4f19118fc4d135a2c049f89ea7c 100644 --- a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentStaffField.tsx +++ b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentStaffField.tsx @@ -109,6 +109,7 @@ export function AppointmentStaffField( endDecorator={<Close fontSize="sm" />} sx={{ minWidth: 0 }} {...getTagProps({ index })} + key={item.value} > {item.label} </Chip> diff --git a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentStaffSelection.tsx b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentStaffSelection.tsx index a34baac204dbf9ad7bcf4af963b7d770bea62934..4f0741ffa3fa1dc371fed35b6150f8aaa7ec9610 100644 --- a/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentStaffSelection.tsx +++ b/employee-portal/src/lib/shared/components/appointmentBlocks/AppointmentStaffSelection.tsx @@ -15,7 +15,8 @@ export const BUTTON_STYLES: SxProps = { export interface AppointmentStaffSelectionProps { physicianOptions: SelectionOption[]; - medicalAssistantsOptions: SelectionOption[]; + medicalAssistantOptions?: SelectionOption[]; + consultantOptions?: SelectionOption[]; blockedStaff: string[]; freeStaff: string[]; validateAvailability: () => void; @@ -41,16 +42,30 @@ export function AppointmentStaffSelection( blockedStaff={props.blockedStaff} /> </Grid> - <Grid xs={4}> - <AppointmentStaffField - name="mfas" - label="MFA" - placeholder="auswählen" - options={props.medicalAssistantsOptions} - freeStaff={props.freeStaff} - blockedStaff={props.blockedStaff} - /> - </Grid> + {props.medicalAssistantOptions && ( + <Grid xs={4}> + <AppointmentStaffField + name="mfas" + label="MFA" + placeholder="auswählen" + options={props.medicalAssistantOptions} + freeStaff={props.freeStaff} + blockedStaff={props.blockedStaff} + /> + </Grid> + )} + {props.consultantOptions && ( + <Grid xs={4}> + <AppointmentStaffField + name="consultants" + label="Berater:in" + placeholder="auswählen" + options={props.consultantOptions} + freeStaff={props.freeStaff} + blockedStaff={props.blockedStaff} + /> + </Grid> + )} <Grid xs={4}> <Button variant="outlined" diff --git a/employee-portal/src/lib/shared/components/appointmentBlocks/WeekdayCheckboxGroup.tsx b/employee-portal/src/lib/shared/components/appointmentBlocks/WeekdayCheckboxGroup.tsx index c4b27246d4b85b8e60160377060aea426b310640..f0d5c5219566d2d18881b5bac64be6d74de82787 100644 --- a/employee-portal/src/lib/shared/components/appointmentBlocks/WeekdayCheckboxGroup.tsx +++ b/employee-portal/src/lib/shared/components/appointmentBlocks/WeekdayCheckboxGroup.tsx @@ -21,20 +21,20 @@ import { CheckboxField } from "@/lib/shared/components/formFields/CheckboxField" export interface CheckboxGroupProps { name: string; - element: WeekdayCheckboxOption[]; + options: WeekdayCheckboxOption[]; label: string; sx?: SxProps; - onChange?: (values: WeekdayCheckboxOption[]) => void; + onChange?: (options: WeekdayCheckboxOption[]) => void; } export function WeekdayCheckboxGroup({ - element, + options, label, ...props }: Readonly<CheckboxGroupProps>) { const { input, meta, helperText } = useBaseField<WeekdayCheckboxOption[]>({ - validate: (value: WeekdayCheckboxOption[]) => { - if (value.length <= 0) { + validate: (options: WeekdayCheckboxOption[] = []) => { + if (!options.length) { return "Bitte mindestens einen Tag auswählen"; } else { return undefined; @@ -59,7 +59,7 @@ export function WeekdayCheckboxGroup({ role="listbox" sx={{ flexDirection: "row", mt: 1, gap: 2 }} > - {element?.map((val, index) => ( + {options?.map((option, index) => ( <ListItem key={index} sx={{ @@ -70,8 +70,8 @@ export function WeekdayCheckboxGroup({ > <CheckboxField name={props.name} - representingValue={val.id} - label={val.label} + representingValue={option.id} + label={option.label} size="sm" /> </ListItem> diff --git a/employee-portal/src/lib/shared/components/archiving/ArchiveAdminView.tsx b/employee-portal/src/lib/shared/components/archiving/ArchiveAdminView.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2eed1d81ed235b904ab1eb93fd917073fd8c7759 --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/ArchiveAdminView.tsx @@ -0,0 +1,38 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ApiUserRole } from "@eshg/employee-portal-api/base"; + +import { + UseBulkUpdateProceduresArchivingRelevance, + UseExportRelevantProcedures, +} from "@/lib/shared/api/mutations/archiving"; +import { UseGetRelevantArchivableProcedures } from "@/lib/shared/api/queries/archiving"; +import { RestrictedPage } from "@/lib/shared/components/RestrictedPage"; +import { ArchiveAdminTable } from "@/lib/shared/components/archiving/components/archiveAdminView/ArchiveAdminTable"; +import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; +import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; +import { Toolbar } from "@/lib/shared/components/layout/Toolbar"; + +export interface ArchiveAdminViewProps { + title: string; + useGetRelevantArchivableProcedures: UseGetRelevantArchivableProcedures; + useExportRelevantProcedures: UseExportRelevantProcedures; + useBulkUpdateProceduresArchivingRelevance: UseBulkUpdateProceduresArchivingRelevance; +} + +export function ArchiveAdminView(props: ArchiveAdminViewProps) { + return ( + <StickyToolbarLayout + toolbar={<Toolbar title={`Archiv-Admin: ${props.title}`} />} + > + <RestrictedPage requiredUserRole={ApiUserRole.ProcedureArchiveAdmin}> + <MainContentLayout fullViewportHeight> + <ArchiveAdminTable {...props} /> + </MainContentLayout> + </RestrictedPage> + </StickyToolbarLayout> + ); +} diff --git a/employee-portal/src/lib/shared/components/archiving/ArchiveView.tsx b/employee-portal/src/lib/shared/components/archiving/ArchiveView.tsx new file mode 100644 index 0000000000000000000000000000000000000000..7ae98c7806e9fb581ad7a98905c345af53243099 --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/ArchiveView.tsx @@ -0,0 +1,39 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ApiUserRole } from "@eshg/employee-portal-api/base"; +import { ApiProcedureType } from "@eshg/employee-portal-api/businessProcedures"; + +import { UseBulkUpdateProceduresArchivingRelevance } from "@/lib/shared/api/mutations/archiving"; +import { + UseGetArchivableProcedures, + UseGetArchivingConfiguration, +} from "@/lib/shared/api/queries/archiving"; +import { RestrictedPage } from "@/lib/shared/components/RestrictedPage"; +import { ArchiveTable } from "@/lib/shared/components/archiving/components/archiveView/ArchiveTable"; +import { MainContentLayout } from "@/lib/shared/components/layout/MainContentLayout"; +import { StickyToolbarLayout } from "@/lib/shared/components/layout/StickyToolbarLayout"; +import { Toolbar } from "@/lib/shared/components/layout/Toolbar"; + +export interface ArchiveViewProps { + title: string; + procedureDetailsRoute: (procedureId: string) => string; + useGetArchivingConfiguration: UseGetArchivingConfiguration; + useGetArchivableProcedures: UseGetArchivableProcedures; + useBulkUpdateProceduresArchivingRelevance: UseBulkUpdateProceduresArchivingRelevance; + additionalFilters: { procedureTypes: ApiProcedureType[] }; +} + +export function ArchiveView({ title, ...props }: ArchiveViewProps) { + return ( + <StickyToolbarLayout toolbar={<Toolbar title={`Archivierung: ${title}`} />}> + <RestrictedPage requiredUserRole={ApiUserRole.ProcedureArchive}> + <MainContentLayout fullViewportHeight> + <ArchiveTable {...props} /> + </MainContentLayout> + </RestrictedPage> + </StickyToolbarLayout> + ); +} diff --git a/employee-portal/src/lib/shared/components/archiving/api/models/archivableProcedure.ts b/employee-portal/src/lib/shared/components/archiving/api/models/archivableProcedure.ts new file mode 100644 index 0000000000000000000000000000000000000000..deaf7375c2adf5f9374bcd1496f7181a3a35def8 --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/api/models/archivableProcedure.ts @@ -0,0 +1,35 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + ApiGetArchivableProceduresResponse, + ApiProcedure, +} from "@eshg/employee-portal-api/businessProcedures"; + +export type ArchivableProcedure = ApiProcedure & { id: string }; + +interface GetArchivableProceduresResponse { + procedures: ArchivableProcedure[]; + totalElements: number; + totalPages: number; +} + +export function mapArchivableProceduresResponse( + response: ApiGetArchivableProceduresResponse, +): GetArchivableProceduresResponse { + return { + procedures: mapProcedures(response.procedures), + totalElements: response.totalElements, + totalPages: response.totalPages, + }; +} + +function mapProcedures(procedures: ApiProcedure[]) { + return procedures.map((procedure) => ({ + // Introduce id for row selection + id: procedure.procedureId, + ...procedure, + })); +} diff --git a/employee-portal/src/lib/shared/components/archiving/components/ArchivingRelevanceChip.tsx b/employee-portal/src/lib/shared/components/archiving/components/ArchivingRelevanceChip.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5227584fa7b028b7919f9245a36fa811b962889d --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/components/ArchivingRelevanceChip.tsx @@ -0,0 +1,27 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ApiArchivingRelevance } from "@eshg/employee-portal-api/businessProcedures"; +import Chip, { ChipProps } from "@mui/joy/Chip"; + +import { archivingRelevanceNames } from "@/lib/shared/components/archiving/constants"; + +const CHIP_COLORS = { + [ApiArchivingRelevance.Default]: "neutral", + [ApiArchivingRelevance.Irrelevant]: "danger", + [ApiArchivingRelevance.Relevant]: "primary", +} satisfies Record<ApiArchivingRelevance, ChipProps["color"]>; + +export function ArchivingRelevanceChip({ + archivingRelevance, +}: { + archivingRelevance: ApiArchivingRelevance; +}) { + return ( + <Chip color={CHIP_COLORS[archivingRelevance]}> + {archivingRelevanceNames[archivingRelevance]} + </Chip> + ); +} diff --git a/employee-portal/src/lib/shared/components/archiving/components/NoProceduresFallback.tsx b/employee-portal/src/lib/shared/components/archiving/components/NoProceduresFallback.tsx new file mode 100644 index 0000000000000000000000000000000000000000..3703068c1202b04505662a5a4c0a7d0cc9fe46de --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/components/NoProceduresFallback.tsx @@ -0,0 +1,27 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { CancelOutlined } from "@mui/icons-material"; +import { Sheet, Stack, Typography } from "@mui/joy"; + +export function NoProceduresFallback({ message }: { message: string }) { + return ( + <Sheet + sx={{ + mt: 2, + flex: 1, + display: "flex", + alignItems: "center", + justifyContent: "center", + border: "none", + }} + > + <Stack margin="auto 0" alignItems="center" gap={3}> + <CancelOutlined fontSize="xl4" /> + <Typography>{message}</Typography> + </Stack> + </Sheet> + ); +} diff --git a/employee-portal/src/lib/shared/components/archiving/components/archiveAdminView/ArchiveAdminTable.tsx b/employee-portal/src/lib/shared/components/archiving/components/archiveAdminView/ArchiveAdminTable.tsx new file mode 100644 index 0000000000000000000000000000000000000000..1936c6c6b26a835057597d66b431f16bdf55592b --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/components/archiveAdminView/ArchiveAdminTable.tsx @@ -0,0 +1,176 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + ApiArchivingRelevance, + ApiGetRelevantArchivableProceduresSortBy, +} from "@eshg/employee-portal-api/businessProcedures"; +import { useFileDownload } from "@eshg/lib-portal/api/files/download"; +import { HiddenContainer } from "@eshg/lib-portal/components/HiddenContainer"; +import { DeleteOutlined, DownloadOutlined } from "@mui/icons-material"; +import { Button } from "@mui/joy"; + +import { ArchiveAdminViewProps } from "@/lib/shared/components/archiving/ArchiveAdminView"; +import { NoProceduresFallback } from "@/lib/shared/components/archiving/components/NoProceduresFallback"; +import { archiveAdminTableColumns } from "@/lib/shared/components/archiving/components/archiveAdminView/archiveAdminTableColumns"; +import { + getRelevantArchivableProceduresFilters, + useArchiveAdminFilterSettings, +} from "@/lib/shared/components/archiving/hooks/useArchiveAdminFilterSettings"; +import { ButtonBar } from "@/lib/shared/components/buttons/ButtonBar"; +import { FilterButton } from "@/lib/shared/components/buttons/FilterButton"; +import { useConfirmationDialog } from "@/lib/shared/components/confirmationDialog/ConfirmationDialogProvider"; +import { FilterSettings } from "@/lib/shared/components/filterSettings/FilterSettings"; +import { FilterSettingsSheet } from "@/lib/shared/components/filterSettings/FilterSettingsSheet"; +import { Pagination } from "@/lib/shared/components/pagination/Pagination"; +import { DataTable } from "@/lib/shared/components/table/DataTable"; +import { TablePage } from "@/lib/shared/components/table/TablePage"; +import { TableSheet } from "@/lib/shared/components/table/TableSheet"; +import { + getSortDirection, + getSortKey, +} from "@/lib/shared/components/table/sorting"; +import { formatFileSize } from "@/lib/shared/helpers/file"; +import { useTableControl } from "@/lib/shared/hooks/searchParams/useTableControl"; + +export type ArchiveAdminTableProps = Omit<ArchiveAdminViewProps, "title">; + +export function ArchiveAdminTable(props: ArchiveAdminTableProps) { + const tableControl = useTableControl({ + serverSideSorting: true, + sortFieldName: "sortKey", + initialSorting: { + id: ApiGetRelevantArchivableProceduresSortBy.ClosedAt, + desc: false, + }, + }); + const filterSettings = useArchiveAdminFilterSettings(); + + const { pageSize, pageNumber } = tableControl.paginationProps; + const { + data: { procedures, totalElements, fileSizeBytes }, + } = props.useGetRelevantArchivableProcedures({ + pageSize, + pageNumber, + sortBy: getSortKey(tableControl.tableSorting), + sortOrder: getSortDirection(tableControl.tableSorting), + ...getRelevantArchivableProceduresFilters(filterSettings.activeValues), + }); + + const exportRelevantProcedures = props.useExportRelevantProcedures(); + const bulkUpdateProceduresArchivingRelevance = + props.useBulkUpdateProceduresArchivingRelevance(); + + const { downloadContainerRef, download: downloadRelevantProcedures } = + useFileDownload(exportRelevantProcedures.mutateAsync); + + const { openConfirmationDialog } = useConfirmationDialog(); + + function handleExportAction() { + openConfirmationDialog({ + title: "Dateien exportieren?", + description: `Möchten Sie die Vorgänge wirklich herunterladen? Die exportierte Datei ist im ZIP-Format und ${formatFileSize(fileSizeBytes)} groß.`, + confirmLabel: "Herunterladen", + color: "danger", + onConfirm: handleExportActionConfirm, + }); + } + + function handleDeleteAction() { + openConfirmationDialog({ + title: "Vorgänge löschen?", + description: `Wollen Sie ${totalElements} ${totalElements === 1 ? "Vorgang" : "Vorgänge"} wirklich unwiderruflich löschen?`, + confirmLabel: "Löschen", + color: "danger", + onConfirm: handleDeleteActionConfirm, + }); + } + + async function handleExportActionConfirm() { + const procedureIds = procedures.map(({ procedureId }) => procedureId); + await downloadRelevantProcedures({ procedureIds }); + } + + function handleDeleteActionConfirm() { + bulkUpdateProceduresArchivingRelevance.mutate({ + procedureIds: procedures.map(({ procedureId }) => procedureId), + archivingRelevance: ApiArchivingRelevance.Irrelevant, + }); + } + + const hasActiveFilters = filterSettings.activeValues.length > 0; + const showTable = hasActiveFilters || totalElements !== 0; + if (!showTable) { + return ( + <> + <ButtonBar left={<FilterButton disabled />} /> + <NoProceduresFallback message="Es liegen keine archivierten Vorgänge vor." /> + </> + ); + } + + return ( + <> + <TablePage + fullHeight + controls={ + <ButtonBar + left={<FilterButton {...filterSettings.filterButtonProps} />} + right={ + totalElements > 0 ? ( + <> + <Button + onClick={handleDeleteAction} + disabled={bulkUpdateProceduresArchivingRelevance.isPending} + loading={bulkUpdateProceduresArchivingRelevance.isPending} + loadingPosition="start" + variant="outlined" + startDecorator={<DeleteOutlined />} + > + Alle löschen + </Button> + <Button + onClick={handleExportAction} + disabled={exportRelevantProcedures.isPending} + loading={exportRelevantProcedures.isPending} + loadingPosition="start" + startDecorator={<DownloadOutlined />} + > + Alle als ZIP exportieren + </Button> + </> + ) : undefined + } + /> + } + filterSettings={ + filterSettings.filterSettingsVisible && ( + <FilterSettingsSheet {...filterSettings.filterSettingsSheetProps}> + <FilterSettings {...filterSettings.filterSettingsProps} /> + </FilterSettingsSheet> + ) + } + data-testid="archiveAdminTable" + > + <TableSheet + footer={ + <Pagination + totalCount={totalElements} + {...tableControl.paginationProps} + /> + } + > + <DataTable + data={procedures} + columns={archiveAdminTableColumns} + sorting={tableControl.tableSorting} + enableSortingRemoval={false} + /> + </TableSheet> + </TablePage> + <HiddenContainer ref={downloadContainerRef} /> + </> + ); +} diff --git a/employee-portal/src/lib/shared/components/archiving/components/archiveAdminView/archiveAdminTableColumns.tsx b/employee-portal/src/lib/shared/components/archiving/components/archiveAdminView/archiveAdminTableColumns.tsx new file mode 100644 index 0000000000000000000000000000000000000000..5866632d72be00eb61acbbfdcab7771fd3c72a7e --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/components/archiveAdminView/archiveAdminTableColumns.tsx @@ -0,0 +1,34 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + ApiGetRelevantArchivableProceduresSortBy, + ApiProcedure, +} from "@eshg/employee-portal-api/businessProcedures"; +import { + formatDate, + formatDateTime, +} from "@eshg/lib-portal/formatters/dateTime"; +import { createColumnHelper } from "@tanstack/react-table"; + +const columnHelper = createColumnHelper<ApiProcedure>(); +export const archiveAdminTableColumns = [ + columnHelper.accessor("closedAt", { + id: ApiGetRelevantArchivableProceduresSortBy.ClosedAt, + header: "Geschlossen am", + cell: (props) => formatDate(props.getValue()), + meta: { + width: "240px", + }, + }), + columnHelper.accessor("exportedAt", { + id: ApiGetRelevantArchivableProceduresSortBy.ExportedAt, + header: "Zuletzt exportiert", + cell: (props) => formatDateTime(props.getValue()), + meta: { + width: "260px", + }, + }), +]; diff --git a/employee-portal/src/lib/shared/components/archiving/components/archiveView/ArchiveTable.tsx b/employee-portal/src/lib/shared/components/archiving/components/archiveView/ArchiveTable.tsx new file mode 100644 index 0000000000000000000000000000000000000000..de7b5198121ef5dc528f00e46ab585ca923416a4 --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/components/archiveView/ArchiveTable.tsx @@ -0,0 +1,153 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ApiGetArchivableProceduresSortBy } from "@eshg/employee-portal-api/businessProcedures"; +import { Alert } from "@eshg/lib-portal/components/Alert"; +import { formatDate } from "@eshg/lib-portal/formatters/dateTime"; +import { endOfMonth, isAfter, startOfYear } from "date-fns"; + +import { ArchiveViewProps } from "@/lib/shared/components/archiving/ArchiveView"; +import { ArchivableProcedure } from "@/lib/shared/components/archiving/api/models/archivableProcedure"; +import { NoProceduresFallback } from "@/lib/shared/components/archiving/components/NoProceduresFallback"; +import { ArchiveTableTitle } from "@/lib/shared/components/archiving/components/archiveView/ArchiveTableTitle"; +import { archiveTableColumns } from "@/lib/shared/components/archiving/components/archiveView/archiveTableColumns"; +import { + getArchivableProceduresFilters, + useArchiveFilterSettings, +} from "@/lib/shared/components/archiving/hooks/useArchiveFilterSettings"; +import { ButtonBar } from "@/lib/shared/components/buttons/ButtonBar"; +import { FilterButton } from "@/lib/shared/components/buttons/FilterButton"; +import { FilterSettings } from "@/lib/shared/components/filterSettings/FilterSettings"; +import { FilterSettingsSheet } from "@/lib/shared/components/filterSettings/FilterSettingsSheet"; +import { Pagination } from "@/lib/shared/components/pagination/Pagination"; +import { DataTable } from "@/lib/shared/components/table/DataTable"; +import { TablePage } from "@/lib/shared/components/table/TablePage"; +import { TableSheet } from "@/lib/shared/components/table/TableSheet"; +import { + getSortDirection, + getSortKey, +} from "@/lib/shared/components/table/sorting"; +import { useTableControl } from "@/lib/shared/hooks/searchParams/useTableControl"; +import { + useRowSelection, + useSyncRowSelection, +} from "@/lib/shared/hooks/table/useRowSelection"; + +export type ArchiveTableProps = Omit<ArchiveViewProps, "title">; + +export function ArchiveTable(props: ArchiveTableProps) { + const { data: configuration } = props.useGetArchivingConfiguration(); + + const tableControl = useTableControl({ + serverSideSorting: true, + sortFieldName: "sortKey", + initialSorting: { + id: ApiGetArchivableProceduresSortBy.ClosedAt, + desc: false, + }, + }); + const filterSettings = useArchiveFilterSettings( + props.additionalFilters.procedureTypes, + configuration, + ); + const { pageSize, pageNumber } = tableControl.paginationProps; + const { + data: { procedures, totalElements }, + } = props.useGetArchivableProcedures({ + pageSize, + pageNumber, + sortBy: getSortKey(tableControl.tableSorting), + sortOrder: getSortDirection(tableControl.tableSorting), + ...getArchivableProceduresFilters(filterSettings.activeValues), + }); + + const { rowSelection, rowSelectionProps } = + useRowSelection<ArchivableProcedure>(); + useSyncRowSelection(rowSelectionProps, procedures); + + const hasActiveFilters = filterSettings.activeValues.length > 0; + const showTable = hasActiveFilters || totalElements !== 0; + + return ( + <> + <GracePeriodAlert gracePeriodMonths={configuration.gracePeriodMonths} /> + {showTable ? ( + <TablePage + fullHeight + controls={ + <ButtonBar + left={<FilterButton {...filterSettings.filterButtonProps} />} + /> + } + filterSettings={ + filterSettings.filterSettingsVisible && ( + <FilterSettingsSheet {...filterSettings.filterSettingsSheetProps}> + <FilterSettings {...filterSettings.filterSettingsProps} /> + </FilterSettingsSheet> + ) + } + data-testid="archiveTable" + > + <TableSheet + title={<ArchiveTableTitle rowSelection={rowSelection} {...props} />} + footer={ + <Pagination + totalCount={totalElements} + {...tableControl.paginationProps} + /> + } + > + <DataTable + data={procedures} + columns={archiveTableColumns} + sorting={tableControl.tableSorting} + enableSortingRemoval={false} + rowSelectionProps={rowSelectionProps} + focusColumnHeader="Geschlossen am" + /> + </TableSheet> + </TablePage> + ) : ( + <> + <ButtonBar left={<FilterButton disabled />} /> + <NoProceduresFallback message="Für dieses Fachmodul liegen keine zu archivierenden Vorgänge vor." /> + </> + )} + </> + ); +} + +function GracePeriodAlert({ + gracePeriodMonths, +}: { + gracePeriodMonths: number; +}) { + const monthIndex = gracePeriodMonths - 1; + const today = new Date(); + const endOfGracePeriod = endOfMonth( + new Date(today.getFullYear(), monthIndex), + ); + + if (isAfter(today, endOfGracePeriod)) { + const startOfNextGracePeriod = startOfYear( + new Date(today.getFullYear() + 1, 0), + ); + return ( + <Alert + color="primary" + sx={{ marginBottom: 2 }} + title={`Die diesjährige Archivierungsperiode ist abgelaufen. Am ${formatDate(startOfNextGracePeriod, "de")} beginnt die nächste Archivierungsperiode.`} + /> + ); + } + + return ( + <Alert + color="primary" + sx={{ marginBottom: 2 }} + title={`Das System hat eine Standard-Aktion für die Vorgänge definiert. Diese wird am ${formatDate(endOfGracePeriod, "de")} ausgeführt, wenn Sie keine manuelle Aktion auswählen.`} + /> + ); +} diff --git a/employee-portal/src/lib/shared/components/archiving/components/archiveView/ArchiveTableTitle.tsx b/employee-portal/src/lib/shared/components/archiving/components/archiveView/ArchiveTableTitle.tsx new file mode 100644 index 0000000000000000000000000000000000000000..784e800801360f1f8e7bd12bb42f751d2426c95b --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/components/archiveView/ArchiveTableTitle.tsx @@ -0,0 +1,127 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ApiArchivingRelevance } from "@eshg/employee-portal-api/businessProcedures"; +import { + DeleteOutlined, + Inventory2Outlined, + SubdirectoryArrowRightOutlined, +} from "@mui/icons-material"; +import { Button, Divider, Sheet, Typography } from "@mui/joy"; +import { RowSelectionState } from "@tanstack/react-table"; + +import { ArchiveTableProps } from "@/lib/shared/components/archiving/components/archiveView/ArchiveTable"; +import { useConfirmationDialog } from "@/lib/shared/components/confirmationDialog/ConfirmationDialogProvider"; +import { mapToRowIds } from "@/lib/shared/hooks/table/useRowSelection"; + +interface ArchiveTableTitleProps extends ArchiveTableProps { + rowSelection: RowSelectionState; +} + +export function ArchiveTableTitle(props: ArchiveTableTitleProps) { + const { openConfirmationDialog } = useConfirmationDialog(); + const selectedProcedureIds = mapToRowIds(props.rowSelection); + + const bulkUpdateProceduresArchivingRelevance = + props.useBulkUpdateProceduresArchivingRelevance(); + const isUpdatePending = bulkUpdateProceduresArchivingRelevance.isPending; + + function handleBulkArchiveAction() { + openConfirmationDialog({ + title: "Vorgänge archivieren?", + description: + "Sind Sie sicher, dass Sie die ausgewählten Vorgänge archivieren möchten?", + confirmLabel: "Für die Archivierung markieren", + children: ( + <Typography textColor="text.secondary"> + Diese Vorgänge werden einem Archiv-Admin vorgelegt und sind nach dem + Archivieren für Sie nicht mehr sichtbar. + </Typography> + ), + color: "danger", + onConfirm: handleBulkArchiveActionConfirm, + }); + } + + function handleBulkArchiveActionConfirm() { + bulkUpdateProceduresArchivingRelevance.mutate({ + procedureIds: selectedProcedureIds, + archivingRelevance: ApiArchivingRelevance.Relevant, + }); + } + + function handleBulkDeleteAction() { + openConfirmationDialog({ + title: "Vorgänge löschen?", + description: + "Sind Sie sicher, dass Sie die ausgewählten Vorgänge löschen möchten? Diese Aktion ist unwiderruflich.", + confirmLabel: "Löschen", + color: "danger", + onConfirm: handleBulkDeleteActionConfirm, + }); + } + + function handleBulkDeleteActionConfirm() { + bulkUpdateProceduresArchivingRelevance.mutate({ + procedureIds: selectedProcedureIds, + archivingRelevance: ApiArchivingRelevance.Irrelevant, + }); + } + + return ( + <Sheet + variant="soft" + sx={{ + display: "flex", + gap: 2, + alignItems: "center", + borderRadius: 0, + height: 48, + padding: (theme) => theme.spacing(0.5, 1.5), + }} + > + <SubdirectoryArrowRightOutlined + sx={{ transform: "rotate(90deg)", fontSize: "1.25rem" }} + /> + <Typography level="body-sm" data-testid="selectedIndicator"> + <Typography fontWeight="bold">{selectedProcedureIds.length}</Typography>{" "} + {selectedProcedureIds.length === 1 ? "Vorgang" : "Vorgänge"} ausgewählt + </Typography> + <Divider orientation="vertical" /> + {selectedProcedureIds.length === 0 && ( + <Typography level="body-sm" color="danger"> + Bitte Vorgänge auswählen + </Typography> + )} + {selectedProcedureIds.length > 0 && ( + <> + <Button + data-testid="archiveButton" + startDecorator={<Inventory2Outlined />} + variant="plain" + color="neutral" + size="sm" + disabled={isUpdatePending} + onClick={handleBulkArchiveAction} + > + Archivieren + </Button> + <Divider orientation="vertical" sx={{ marginY: 1 }} /> + <Button + data-testid="deleteButton" + startDecorator={<DeleteOutlined />} + variant="plain" + color="neutral" + size="sm" + disabled={isUpdatePending} + onClick={handleBulkDeleteAction} + > + Löschen + </Button> + </> + )} + </Sheet> + ); +} diff --git a/employee-portal/src/lib/shared/components/archiving/components/archiveView/archiveTableColumns.tsx b/employee-portal/src/lib/shared/components/archiving/components/archiveView/archiveTableColumns.tsx new file mode 100644 index 0000000000000000000000000000000000000000..41122fa1316d0cbe7ee3b091b7127247f8756c6b --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/components/archiveView/archiveTableColumns.tsx @@ -0,0 +1,45 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ApiGetArchivableProceduresSortBy } from "@eshg/employee-portal-api/businessProcedures"; +import { formatDate } from "@eshg/lib-portal/formatters/dateTime"; +import { createColumnHelper } from "@tanstack/react-table"; + +import { ArchivableProcedure } from "@/lib/shared/components/archiving/api/models/archivableProcedure"; +import { ArchivingRelevanceChip } from "@/lib/shared/components/archiving/components/ArchivingRelevanceChip"; +import { procedureTypeNames } from "@/lib/shared/components/procedures/constants"; + +const columnHelper = createColumnHelper<ArchivableProcedure>(); +export const archiveTableColumns = [ + columnHelper.accessor("closedAt", { + id: ApiGetArchivableProceduresSortBy.ClosedAt, + header: "Geschlossen am", + cell: (props) => formatDate(props.getValue()), + meta: { + width: "240px", + }, + }), + columnHelper.accessor("procedureType", { + id: ApiGetArchivableProceduresSortBy.ProcedureType, + header: "Vorgangsart", + cell: (props) => procedureTypeNames[props.getValue()], + meta: { + width: "260px", + }, + }), + columnHelper.accessor( + "archivingRelevanceSettings.defaultArchivingRelevance", + { + header: "Standard-Aktion", + cell: (props) => ( + <ArchivingRelevanceChip archivingRelevance={props.getValue()} /> + ), + enableSorting: false, + meta: { + width: "260px", + }, + }, + ), +]; diff --git a/employee-portal/src/lib/shared/components/archiving/constants.ts b/employee-portal/src/lib/shared/components/archiving/constants.ts new file mode 100644 index 0000000000000000000000000000000000000000..d930b79dec4b905222b2dc1f788bbc85e19e9dfe --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/constants.ts @@ -0,0 +1,12 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ApiArchivingRelevance } from "@eshg/employee-portal-api/base"; + +export const archivingRelevanceNames = { + [ApiArchivingRelevance.Default]: "Standard", + [ApiArchivingRelevance.Irrelevant]: "Löschen", + [ApiArchivingRelevance.Relevant]: "Archivieren", +} satisfies Record<ApiArchivingRelevance, string>; diff --git a/employee-portal/src/lib/shared/components/archiving/helper.ts b/employee-portal/src/lib/shared/components/archiving/helper.ts new file mode 100644 index 0000000000000000000000000000000000000000..f0d61de36cf76e9821a0742a965d9447e75a7aa0 --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/helper.ts @@ -0,0 +1,37 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { isDateString } from "@eshg/lib-portal/helpers/dateTime"; + +import { FilterValue } from "@/lib/shared/components/filterSettings/models/FilterValue"; + +export function getFilterDate(filterValues: FilterValue[], key: string) { + const value = filterValues.find((filterValue) => filterValue.key === key); + if (value?.type === "Date" && isDateString(value.selectedValue)) { + return new Date(value.selectedValue); + } + return undefined; +} + +export function getFilterSelectedValues<T extends string>( + filterValues: FilterValue[], + key: string, + targetEnum: Record<string, T>, +): Set<T> | undefined { + const value = filterValues.find((filterValue) => filterValue.key === key); + if (!value || !("selectedValues" in value)) { + return undefined; + } + + const targetEnumValues: string[] = Object.values(targetEnum); + const filteredSelectedValues = value.selectedValues.filter( + (selectedValue): selectedValue is T => + targetEnumValues.includes(selectedValue), + ); + if (filteredSelectedValues.length === 0) { + return undefined; + } + return new Set(filteredSelectedValues); +} diff --git a/employee-portal/src/lib/shared/components/archiving/hooks/useArchiveAdminFilterSettings.ts b/employee-portal/src/lib/shared/components/archiving/hooks/useArchiveAdminFilterSettings.ts new file mode 100644 index 0000000000000000000000000000000000000000..75a6f8736bc883535a20b2b2feceea559b705e0c --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/hooks/useArchiveAdminFilterSettings.ts @@ -0,0 +1,68 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { GetRelevantArchivableProceduresRequest } from "@eshg/employee-portal-api/businessProcedures"; + +import { getFilterDate } from "@/lib/shared/components/archiving/helper"; +import { FilterDefinition } from "@/lib/shared/components/filterSettings/models/FilterDefinition"; +import { FilterValue } from "@/lib/shared/components/filterSettings/models/FilterValue"; +import { UseFilterSettings } from "@/lib/shared/components/filterSettings/useFilterSettings"; +import { useSearchParamFilterSettings } from "@/lib/shared/components/filterSettings/useSearchParamFilterSettings"; +import { getSelectedFilterValues } from "@/lib/shared/components/procedures/helper"; + +const FILTER_KEYS = { + closedAtDay: "closedAtDay", + visibility: "visibility", +}; +const FILTER_VISIBILITY_VALUES = { + hideExported: "hideExported", +}; + +export function useArchiveAdminFilterSettings(): UseFilterSettings { + const filterDefinitions: FilterDefinition[] = [ + { + type: "Date", + key: FILTER_KEYS.closedAtDay, + name: "Geschlossen am", + }, + { + type: "Enum", + key: FILTER_KEYS.visibility, + name: "Sichtbarkeit", + inAccordion: false, + options: [ + { + label: "Bereits exportierte Vorgänge verbergen", + value: FILTER_VISIBILITY_VALUES.hideExported, + }, + ], + }, + ]; + + return useSearchParamFilterSettings({ + definitions: filterDefinitions, + onValuesSubmit: () => { + // active values are synced via SearchParamStateProvider + }, + showSearch: false, + }); +} + +export function getRelevantArchivableProceduresFilters( + filterValues: FilterValue[], +): Pick<GetRelevantArchivableProceduresRequest, "closedAtDay" | "exported"> { + const visibilityValues = getSelectedFilterValues( + filterValues, + FILTER_KEYS.visibility, + ); + const hideExported = visibilityValues.includes( + FILTER_VISIBILITY_VALUES.hideExported, + ); + + return { + closedAtDay: getFilterDate(filterValues, FILTER_KEYS.closedAtDay), + exported: hideExported ? false : undefined, + }; +} diff --git a/employee-portal/src/lib/shared/components/archiving/hooks/useArchiveFilterSettings.ts b/employee-portal/src/lib/shared/components/archiving/hooks/useArchiveFilterSettings.ts new file mode 100644 index 0000000000000000000000000000000000000000..d483a5ba1438ef11ef22c7d9db94da51ebe268d0 --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/hooks/useArchiveFilterSettings.ts @@ -0,0 +1,130 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + ApiArchivingRelevance, + ApiGetArchivingConfigurationResponse, + ApiProcedureType, + GetArchivableProceduresRequest, +} from "@eshg/employee-portal-api/businessProcedures"; + +import { archivingRelevanceNames } from "@/lib/shared/components/archiving/constants"; +import { + getFilterDate, + getFilterSelectedValues, +} from "@/lib/shared/components/archiving/helper"; +import { FilterDefinition } from "@/lib/shared/components/filterSettings/models/FilterDefinition"; +import { FilterValue } from "@/lib/shared/components/filterSettings/models/FilterValue"; +import { UseFilterSettings } from "@/lib/shared/components/filterSettings/useFilterSettings"; +import { useSearchParamFilterSettings } from "@/lib/shared/components/filterSettings/useSearchParamFilterSettings"; +import { procedureTypeNames } from "@/lib/shared/components/procedures/constants"; + +const FILTER_KEYS = { + closedAtDay: "closedAtDay", + defaultArchivingRelevance: "defaultArchivingRelevance", + procedureType: "procedureType", +}; + +export function useArchiveFilterSettings( + procedureTypes: ApiProcedureType[], + configuration: ApiGetArchivingConfigurationResponse, +): UseFilterSettings { + // A list of procedure types is provided by the frontend, + // to obtain a list of relevant archivingRelevances for the current view from the configuration + const availableArchivingRelevances = buildArchivingRelevanceFilter( + procedureTypes, + configuration, + ); + const filterDefinitions: FilterDefinition[] = [ + { + type: "Date", + key: FILTER_KEYS.closedAtDay, + name: "Geschlossen am", + }, + ...(procedureTypes.length > 1 + ? ([ + { + type: "Enum", + key: FILTER_KEYS.procedureType, + name: "Vorgangsart", + options: buildOptionsFromProcedureTypes(procedureTypes), + }, + ] as const) + : []), + ...(availableArchivingRelevances.size > 1 + ? ([ + { + type: "Enum", + key: FILTER_KEYS.defaultArchivingRelevance, + name: "Standard-Aktion", + options: buildOptionsFromArchivingRelevances( + availableArchivingRelevances, + ), + }, + ] as const) + : []), + ]; + + return useSearchParamFilterSettings({ + definitions: filterDefinitions, + onValuesSubmit: () => { + // active values are synced via SearchParamStateProvider + }, + showSearch: false, + }); +} + +export function getArchivableProceduresFilters( + filterValues: FilterValue[], +): Pick< + GetArchivableProceduresRequest, + "closedAtDay" | "defaultArchivingRelevance" | "procedureType" +> { + return { + closedAtDay: getFilterDate(filterValues, FILTER_KEYS.closedAtDay), + procedureType: getFilterSelectedValues( + filterValues, + FILTER_KEYS.procedureType, + ApiProcedureType, + ), + defaultArchivingRelevance: getFilterSelectedValues( + filterValues, + FILTER_KEYS.defaultArchivingRelevance, + ApiArchivingRelevance, + ), + }; +} + +function buildArchivingRelevanceFilter( + procedureTypes: ApiProcedureType[], + configuration: ApiGetArchivingConfigurationResponse, +) { + return new Set( + procedureTypes + .map( + (procedureType) => + configuration.archivingDetails[procedureType]?.archivingRelevance, + ) + .filter((archivingRelevance) => archivingRelevance !== undefined) + .sort() + .reverse(), + ); +} + +function buildOptionsFromProcedureTypes(procedureTypes: ApiProcedureType[]) { + return procedureTypes.map((value) => ({ + value, + label: procedureTypeNames[value], + })); +} + +function buildOptionsFromArchivingRelevances( + archivingRelevances: Set<ApiArchivingRelevance>, +) { + return Array.from(archivingRelevances).map((value) => ({ + value, + label: archivingRelevanceNames[value], + })); +} diff --git a/employee-portal/src/lib/shared/components/archiving/shared/routes.ts b/employee-portal/src/lib/shared/components/archiving/shared/routes.ts new file mode 100644 index 0000000000000000000000000000000000000000..afc65100c5b53ed776a9141b99ec321c2fc387f8 --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/shared/routes.ts @@ -0,0 +1,25 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +export const routes = { + archive: { + module: { + inspection: `/archiving/inspection`, + measlesProtection: `/archiving/measles-protection`, + schoolEntry: `/archiving/school-entry`, + travelMedicine: `/archiving/travel-medicine`, + stiProtection: `/archiving/sti-protection`, + }, + }, + archiveAdmin: { + module: { + inspection: `/archiving-admin/inspection`, + measlesProtection: `/archiving-admin/measles-protection`, + schoolEntry: `/archiving-admin/school-entry`, + travelMedicine: `/archiving-admin/travel-medicine`, + stiProtection: `/archiving-admin/sti-protection`, + }, + }, +} as const; diff --git a/employee-portal/src/lib/shared/components/archiving/shared/sideNavigationItem.tsx b/employee-portal/src/lib/shared/components/archiving/shared/sideNavigationItem.tsx new file mode 100644 index 0000000000000000000000000000000000000000..9008341422029c3d5ebc1d0280db41bb2f92da33 --- /dev/null +++ b/employee-portal/src/lib/shared/components/archiving/shared/sideNavigationItem.tsx @@ -0,0 +1,77 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ApiUserRole } from "@eshg/employee-portal-api/base"; +import InventoryIcon from "@mui/icons-material/Inventory"; + +import { SideNavigationItem } from "@/lib/baseModule/components/layout/sideNavigation/types"; +import { hasUserRole } from "@/lib/shared/helpers/accessControl"; + +import { routes } from "./routes"; + +export const sideNavigationItems: SideNavigationItem[] = [ + { + name: "Archivierung", + decorator: <InventoryIcon />, + subItems: [ + { + name: "Begehung", + href: routes.archive.module.inspection, + accessCheck: hasUserRole(ApiUserRole.ProcedureArchive), + }, + { + name: "Einschulung", + href: routes.archive.module.schoolEntry, + accessCheck: hasUserRole(ApiUserRole.ProcedureArchive), + }, + { + name: "Impfberatung", + href: routes.archive.module.travelMedicine, + accessCheck: hasUserRole(ApiUserRole.ProcedureArchive), + }, + { + name: "Masernschutz", + href: routes.archive.module.measlesProtection, + accessCheck: hasUserRole(ApiUserRole.ProcedureArchive), + }, + { + name: "HIV-STI", + href: routes.archive.module.stiProtection, + accessCheck: hasUserRole(ApiUserRole.ProcedureArchive), + }, + ], + }, + { + name: "Archiv-Admin", + decorator: <InventoryIcon />, + subItems: [ + { + name: "Begehung", + href: routes.archiveAdmin.module.inspection, + accessCheck: hasUserRole(ApiUserRole.ProcedureArchiveAdmin), + }, + { + name: "Einschulung", + href: routes.archiveAdmin.module.schoolEntry, + accessCheck: hasUserRole(ApiUserRole.ProcedureArchiveAdmin), + }, + { + name: "Impfberatung", + href: routes.archiveAdmin.module.travelMedicine, + accessCheck: hasUserRole(ApiUserRole.ProcedureArchiveAdmin), + }, + { + name: "Masernschutz", + href: routes.archiveAdmin.module.measlesProtection, + accessCheck: hasUserRole(ApiUserRole.ProcedureArchiveAdmin), + }, + { + name: "HIV-STI", + href: routes.archiveAdmin.module.stiProtection, + accessCheck: hasUserRole(ApiUserRole.ProcedureArchiveAdmin), + }, + ], + }, +]; diff --git a/employee-portal/src/lib/shared/components/chat/MessageTeaserProvider.tsx b/employee-portal/src/lib/shared/components/chat/MessageTeaserProvider.tsx index d91b5ff6aef2deb58402465404687fe3f97a5e52..e47ff6f7d3954ed1685a4f6e4fddcfe2ebf9fb80 100644 --- a/employee-portal/src/lib/shared/components/chat/MessageTeaserProvider.tsx +++ b/employee-portal/src/lib/shared/components/chat/MessageTeaserProvider.tsx @@ -24,6 +24,8 @@ import { v4 as uuidv4 } from "uuid"; import { useChat } from "@/lib/businessModules/chat/shared/ChatProvider"; import { routes } from "@/lib/businessModules/chat/shared/routes"; +import { Presence } from "@/lib/businessModules/chat/shared/types"; +import { getStatusColor } from "@/lib/businessModules/chat/shared/utils"; interface SnackbarValues { username: string; @@ -100,7 +102,9 @@ function BaseSnackbar({ snackbar, onClose }: Readonly<BaseSnackbarProps>) { width: "0.625rem", height: "0.625rem", borderRadius: "100%", - backgroundColor: getColor(snackbar.userPresence), + backgroundColor: getStatusColor( + snackbar.userPresence as Presence, + ), marginRight: 0.8, }} ></Box> @@ -122,7 +126,7 @@ function BaseSnackbar({ snackbar, onClose }: Readonly<BaseSnackbarProps>) { <IconButton aria-label="Schließen" onClick={onClose} - sx={{ color: "focusVisible" }} + color="primary" > <CloseIcon /> </IconButton> @@ -198,21 +202,6 @@ const SnackbarContext = createContext<{ setSnackbar: Dispatch<SetStateAction<SnackbarValues | undefined>>; }>(null!); -function getColor(status: string) { - if (status === undefined) { - return; - } - if (status === "online") { - return "success.500"; - } - if (status === "offline") { - return "danger.500"; - } - if (status === "unavailable") { - return "neutral.500"; - } -} - export function MessageTeaserProvider({ children, }: Readonly<{ children: ReactNode }>) { diff --git a/employee-portal/src/lib/shared/components/detailsSection/SectionHeader.tsx b/employee-portal/src/lib/shared/components/detailsSection/SectionHeader.tsx index e33303898150bdc07cc423998fd8d88106d3a082..b5807669902ddf8f77f6fbbd68c263d568338a2c 100644 --- a/employee-portal/src/lib/shared/components/detailsSection/SectionHeader.tsx +++ b/employee-portal/src/lib/shared/components/detailsSection/SectionHeader.tsx @@ -35,6 +35,7 @@ export function SectionHeader({ </Grid> <Grid container direction="row" gap={1} sx={{ marginLeft: "auto" }}> {buttons} + {/* TODO: ISSUE-5586: This is technical debt. These actions should be included via a wrapping component or by adding these controls in the component that uses it. */} {isDefined(onDelete) && ( <IconButton aria-label={`${title} löschen`} diff --git a/employee-portal/src/lib/shared/components/filterSettings/FilterSettings.tsx b/employee-portal/src/lib/shared/components/filterSettings/FilterSettings.tsx index 928e010aa5e8b4a69cae2743f8bd467db3c35fba..6c7e115c400b62d80bddbf0c950d892999dc3296 100644 --- a/employee-portal/src/lib/shared/components/filterSettings/FilterSettings.tsx +++ b/employee-portal/src/lib/shared/components/filterSettings/FilterSettings.tsx @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { isDefined } from "remeda"; + import { SearchableGroup, SearchableGroupItem, @@ -33,7 +35,9 @@ function mapDefinitionsToSearchableGroups( ): SearchableGroup<FilterGroupItem>[] { return definitions.map((definition) => ({ name: definition.name, - inAccordion: !["EnumSingle", "Date"].includes(definition.type), + inAccordion: isDefined(definition.inAccordion) + ? definition.inAccordion + : !["EnumSingle", "Date"].includes(definition.type), items: [ { key: definition.key, diff --git a/employee-portal/src/lib/shared/components/filterSettings/models/FilterDefinition.ts b/employee-portal/src/lib/shared/components/filterSettings/models/FilterDefinition.ts index 177a1b3f8cb76e9522cb7ee37d6698c70ce3e231..8ce83933a95bb784b32f955fb1589e297110572e 100644 --- a/employee-portal/src/lib/shared/components/filterSettings/models/FilterDefinition.ts +++ b/employee-portal/src/lib/shared/components/filterSettings/models/FilterDefinition.ts @@ -13,6 +13,8 @@ import { EnumSingleFilterDefinition } from "./EnumSingleFilter"; export interface FilterDefinitionBase { name: string; key: string; + /** allows overwriting render option of group */ + inAccordion?: boolean; } export type FilterDefinition = diff --git a/employee-portal/src/lib/shared/components/filterSettings/models/mapDraftToActiveValues.ts b/employee-portal/src/lib/shared/components/filterSettings/models/mapDraftToActiveValues.ts index 78d720eb1697280cd3fc1d0afd2c89e4e5b940dd..15b37477f3a63cae33cf2c6bc0238505342ae025 100644 --- a/employee-portal/src/lib/shared/components/filterSettings/models/mapDraftToActiveValues.ts +++ b/employee-portal/src/lib/shared/components/filterSettings/models/mapDraftToActiveValues.ts @@ -30,7 +30,10 @@ export function mapDraftToActiveValues( return draftValue; } }) - .filter(isNonNull); + .filter(isNonNull) + .toSorted((draftValueA, draftValueB) => + draftValueA.key.localeCompare(draftValueB.key), + ); } function mapNumber( diff --git a/employee-portal/src/lib/shared/components/filterSettings/useFilterSettings.ts b/employee-portal/src/lib/shared/components/filterSettings/useFilterSettings.ts index 9baa599164b2577d42e0c1c7d3d84306d31cf9e7..50794c9d7fc773b03219ee118782b175fd7b70de 100644 --- a/employee-portal/src/lib/shared/components/filterSettings/useFilterSettings.ts +++ b/employee-portal/src/lib/shared/components/filterSettings/useFilterSettings.ts @@ -57,6 +57,7 @@ export interface UseFilterSettingsParams { } export interface UseFilterSettings { + activeValues: FilterValue[]; filterSettingsVisible: boolean; filterButtonProps: FilterButtonProps; filterSettingsProps: FilterSettingsProps; @@ -220,6 +221,7 @@ export function useFilterSettings({ }; return { + activeValues, filterSettingsVisible, filterButtonProps, filterSettingsProps, diff --git a/employee-portal/src/lib/shared/components/filterSettings/useSearchParamFilterSettings.ts b/employee-portal/src/lib/shared/components/filterSettings/useSearchParamFilterSettings.ts new file mode 100644 index 0000000000000000000000000000000000000000..438d399e35a79b2aebb6c03f1a09e743a6f61ea5 --- /dev/null +++ b/employee-portal/src/lib/shared/components/filterSettings/useSearchParamFilterSettings.ts @@ -0,0 +1,29 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + UseFilterSettings, + UseFilterSettingsParams, + useFilterSettings, +} from "@/lib/shared/components/filterSettings/useFilterSettings"; +import { useSearchParamStateProvider } from "@/lib/shared/components/filterSettings/useSearchParamStateProvider"; + +export type UseSearchParamFilterSettingsParams = Omit< + UseFilterSettingsParams, + "stateProvider" +>; + +export function useSearchParamFilterSettings( + params: UseSearchParamFilterSettingsParams, +): UseFilterSettings { + const searchParamStateProvider = useSearchParamStateProvider( + params.definitions, + ); + + return useFilterSettings({ + ...params, + stateProvider: searchParamStateProvider, + }); +} diff --git a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/useSearchParamStateProvider.ts b/employee-portal/src/lib/shared/components/filterSettings/useSearchParamStateProvider.ts similarity index 93% rename from employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/useSearchParamStateProvider.ts rename to employee-portal/src/lib/shared/components/filterSettings/useSearchParamStateProvider.ts index f6cb03948199b9828c0b73ab6c64da9a03c6e40a..b5a43d7681cd2b5f76d5207f55a5e5d63a749255 100644 --- a/employee-portal/src/lib/businessModules/measlesProtection/components/procedures/proceduresTable/useSearchParamStateProvider.ts +++ b/employee-portal/src/lib/shared/components/filterSettings/useSearchParamStateProvider.ts @@ -1,11 +1,12 @@ /** * Copyright 2024 cronn GmbH - * SPDX-License-Identifier: AGPL-3.0-only + * SPDX-License-Identifier: Apache-2.0 */ import { ReadonlyURLSearchParams, usePathname, + useRouter, useSearchParams, } from "next/navigation"; import { SetStateAction, useCallback, useState } from "react"; @@ -177,12 +178,14 @@ export function paramValuesToActiveValue( export function useSearchParamStateProvider( filterDefinitions: FilterDefinition[], + useRouterReplace = false, ): FilterSettingsStateProvider { const [filterSettingsVisible, setFilterSettingsVisible] = useSearchParam( "filtersOpen", "boolean", ); + const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); const activeValues = filterDefinitions @@ -216,9 +219,15 @@ export function useSearchParamStateProvider( newSearchParams, ); - setWindowSearchParams(pathname, newAndRemovedSearchParams, false); + if (useRouterReplace) { + const paramsString = newAndRemovedSearchParams.toString(); + const query = paramsString && `?${paramsString}`; + router.replace(`${pathname}${query}`); + } else { + setWindowSearchParams(pathname, newAndRemovedSearchParams, false); + } }, - [searchParams, pathname, activeValues], + [searchParams, activeValues, useRouterReplace, router, pathname], ); const [errorMessages, setErrorMessages] = useState([] as string[]); diff --git a/employee-portal/src/lib/shared/components/infoTile/InfoTile.tsx b/employee-portal/src/lib/shared/components/infoTile/InfoTile.tsx index c7c0795ea5bb55803a5a4ce5b41d03728c5e98ec..6792b8a939af597a4f62b497f3864bdbf973ec4e 100644 --- a/employee-portal/src/lib/shared/components/infoTile/InfoTile.tsx +++ b/employee-portal/src/lib/shared/components/infoTile/InfoTile.tsx @@ -15,6 +15,7 @@ export interface InfoTileProps extends RequiresChildren { title: string; onEdit?: () => void; footer?: ReactNode; + controls?: ReactNode; } export function InfoTile({ @@ -23,11 +24,17 @@ export function InfoTile({ onEdit, children, footer, + controls, }: InfoTileProps) { return ( <InformationSheet> <div style={{ flexGrow: 1 }}> - <DetailsSection name={name} title={title} onEdit={onEdit}> + <DetailsSection + name={name} + title={title} + onEdit={onEdit} + buttons={controls} + > <Grid container columns={1} spacing={2} style={{ flexGrow: 1 }}> <Grid xs sx={{ flex: 1 }}> <Stack spacing={2}>{children}</Stack> diff --git a/employee-portal/src/lib/shared/components/modal/DataField.tsx b/employee-portal/src/lib/shared/components/modal/DataField.tsx new file mode 100644 index 0000000000000000000000000000000000000000..da86d19b49ac5be4c2adc7b92283729f27679eba --- /dev/null +++ b/employee-portal/src/lib/shared/components/modal/DataField.tsx @@ -0,0 +1,53 @@ +/** + * Copyright 2024 cronn GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Grid, Typography, TypographyProps } from "@mui/joy"; +import { SxProps } from "@mui/joy/styles/types"; + +import { multiLineEllipsis } from "@/lib/baseModule/theme/theme"; + +interface ResponsiveTypographyProps extends TypographyProps { + linesToShow?: number; + sx?: SxProps; + value: string; +} +export function ResponsiveTypography({ + linesToShow = 1, + sx, + value, + ...typographyProps +}: ResponsiveTypographyProps) { + return ( + <Typography + sx={ + { + ...multiLineEllipsis(linesToShow), + ...sx, + } as SxProps + } + slotProps={{ + root: { + title: value, + }, + }} + {...typographyProps} + > + {value} + </Typography> + ); +} + +export function DataField({ label, value }: { label: string; value: string }) { + return ( + <Grid container xxs={12}> + <Grid xxs={12} sm={3}> + <ResponsiveTypography level="body-md" sx={{ mr: 2 }} value={label} /> + </Grid> + <Grid xxs={12} sm={9}> + <ResponsiveTypography level="title-md" fontWeight="600" value={value} /> + </Grid> + </Grid> + ); +} diff --git a/employee-portal/src/lib/shared/components/table/TableSheet.tsx b/employee-portal/src/lib/shared/components/table/TableSheet.tsx index c19a144ecf19f0802c05e2ef2266619a19f690d4..4767bbcbf5b95822da60b052762e1c0f9ea62fa2 100644 --- a/employee-portal/src/lib/shared/components/table/TableSheet.tsx +++ b/employee-portal/src/lib/shared/components/table/TableSheet.tsx @@ -3,12 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { LoadingOverlay } from "@eshg/lib-portal/components/LoadingOverlay"; import { RequiresChildren } from "@eshg/lib-portal/types/react"; -import { Box, Sheet, styled } from "@mui/joy"; +import { Box, Sheet, Theme, styled } from "@mui/joy"; import { ReactElement, ReactNode } from "react"; -import { LoadingOverlay } from "@/lib/shared/components/LoadingOverlay"; - export const StyledSheet = styled(Sheet)(({ theme }) => ({ flex: 1, minHeight: 0, @@ -18,10 +17,6 @@ export const StyledSheet = styled(Sheet)(({ theme }) => ({ gap: theme.spacing(2), })); -export const StyledLoadingOverlay = styled(LoadingOverlay)(({ theme }) => ({ - zIndex: theme.zIndex.table, -})); - export interface TableSheetProps extends RequiresChildren { loading?: boolean; hideTable?: boolean; @@ -35,7 +30,11 @@ export function TableSheet(props: TableSheetProps): ReactElement { {props.title} {props.hideTable ? <Box flex={1} overflow="auto" /> : props.children} {props.footer} - {props.loading && <StyledLoadingOverlay />} + {props.loading && <LoadingOverlay zIndex={zIndexTable} />} </StyledSheet> ); } + +function zIndexTable(theme: Theme): number { + return theme.zIndex.table; +} diff --git a/employee-portal/src/serviceWorker/sw/index.ts b/employee-portal/src/serviceWorker/sw/index.ts index 35a45c4a212669fd7a460accfd74632c44683a33..0c2ec655771b624b73a58ed842a2aca3899f0975 100644 --- a/employee-portal/src/serviceWorker/sw/index.ts +++ b/employee-portal/src/serviceWorker/sw/index.ts @@ -40,6 +40,10 @@ import { deleteIncidentFromCache, updateIncidentInCache, } from "@/serviceWorker/sw/inspection/controller/updateIncidents"; +import { + API_INSPECTION_INSPECTIONS_INSPECTION, + updateInspectionInCache, +} from "@/serviceWorker/sw/inspection/controller/updateInspection"; import { updatePacklistCache } from "@/serviceWorker/sw/inspection/controller/updatePacklists"; import { getFacilities } from "@/serviceWorker/sw/inspection/service/getFacilities"; import { finalizeInspection } from "@/serviceWorker/sw/inspection/service/updateInspection"; @@ -134,6 +138,13 @@ registerRoute( "PATCH", ); +registerRoute( + ({ url: { pathname } }) => + API_INSPECTION_INSPECTIONS_INSPECTION.test(pathname), + getApiPostHandler(updateInspectionInCache), + "PATCH", +); + registerRoute( ({ url: { pathname } }) => API_INSPECTION_INSPECTIONS_INCIDENTS.test(pathname), diff --git a/employee-portal/src/serviceWorker/sw/inspection/controller/updateInspection.ts b/employee-portal/src/serviceWorker/sw/inspection/controller/updateInspection.ts new file mode 100644 index 0000000000000000000000000000000000000000..172d95e7ba39349aab4632a83c885ac028731657 --- /dev/null +++ b/employee-portal/src/serviceWorker/sw/inspection/controller/updateInspection.ts @@ -0,0 +1,56 @@ +/** + * Copyright 2024 SCOOP Software GmbH, cronn GmbH + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { + ApiInspectionToJSON, + ApiUpdateInspectionRequestFromJSON, +} from "@eshg/employee-portal-api/inspection"; + +import { uuidV4Re } from "@/serviceWorker/common/common"; +import { getFromApiCache, writeToApiCache } from "@/serviceWorker/sw/cache"; +import { getInspection } from "@/serviceWorker/sw/inspection/service/updateInspection"; +import { + UpdateCacheCallbackParam, + UpdateCacheCallbackReturnValue, +} from "@/serviceWorker/sw/requestHandlers"; +import { requireNonNullish } from "@/serviceWorker/sw/util"; + +export const API_INSPECTION_INSPECTIONS_INSPECTION = new RegExp( + `^/api/inspection/inspections/(?<inspectionId>${uuidV4Re})$`, + "i", +); + +export function getApiInspectionPath(inspectionId: string) { + return `/api/inspection/inspections/${inspectionId}`; +} + +export async function updateInspectionInCache({ + requestPath, + request, +}: UpdateCacheCallbackParam): UpdateCacheCallbackReturnValue { + const pathMatch = + API_INSPECTION_INSPECTIONS_INSPECTION.exec(requestPath)?.groups; + const inspectionId = requireNonNullish(pathMatch?.inspectionId); + const updateInspectionRequest = ApiUpdateInspectionRequestFromJSON( + JSON.parse(await request.clone().text()), + ); + + const inspectionResponse = await getInspection(inspectionId); + const inspection = inspectionResponse.inspectionResponse; + + // For now, we only support writing the notes. + inspection.notes = updateInspectionRequest.notes; + + const getRequestPath = getApiInspectionPath(inspectionId); + const response = await getFromApiCache(getRequestPath); + + await writeToApiCache( + getRequestPath, + new Response(JSON.stringify(ApiInspectionToJSON(inspection)), response), + ); + + const responseBody = JSON.stringify(ApiInspectionToJSON(inspection)); + return { responseBody, request }; +} diff --git a/lib-portal/src/api/clientOnlyMiddleware.ts b/lib-portal/src/api/clientOnlyMiddleware.ts index f3d11e2d4fd8aa324e948a55b6f3b8c9926c2d27..f67d0dbedb42803257b8eb734d69e8a8eb43e364 100644 --- a/lib-portal/src/api/clientOnlyMiddleware.ts +++ b/lib-portal/src/api/clientOnlyMiddleware.ts @@ -4,11 +4,22 @@ */ import { Middleware } from "@eshg/employee-portal-api/base"; +import { BailoutToCSRError } from "next/dist/shared/lib/lazy-dynamic/bailout-to-csr"; +/** + * Requests to the backend will only succeed on the client side. + * During server-side rendering, we do not want to make requests to the backend because they will always fail. + * Instead, we exit server-side rendering by throwing an error. + * React will fall back to the Suspense boundary and stop rendering on the server side. + * + * See: https://react.dev/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content + */ export const clientOnlyMiddleware = { async pre() { if (typeof window === "undefined") { - throw new Error( + // To prevent this artificial error from appearing in the browser console, we use a special Next.js error type: `BailoutToCSRError`. + // This error type is filtered out by Next.js during hydration (see `onRecoverableError` in React docs and Next.js implementation). + throw new BailoutToCSRError( "Skipped client-only request on server. This error can be ignored.", ); } diff --git a/lib-portal/src/components/LoadingOverlay.tsx b/lib-portal/src/components/LoadingOverlay.tsx index 6abe31cb585362e5db61acb705287fb8318b8915..46c3a6bb646492f0cfdae45bff81dfe45c8be9eb 100644 --- a/lib-portal/src/components/LoadingOverlay.tsx +++ b/lib-portal/src/components/LoadingOverlay.tsx @@ -17,9 +17,16 @@ const Backdrop = styled(Box)(({ theme }) => ({ left: 0, })); -export function LoadingOverlay(props: Pick<BoxProps, "component" | "sx">) { +export function LoadingOverlay( + props: Pick<BoxProps, "component" | "sx" | "zIndex">, +) { return ( - <Backdrop component={props.component} sx={props.sx} aria-hidden="true"> + <Backdrop + component={props.component} + sx={props.sx} + zIndex={props.zIndex} + aria-hidden="true" + > <LoadingIndicator fullHeight /> </Backdrop> ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e9010df070249746ac17ce24a6198343cf387a92..8d8373a56b4a7da8ed9baf6a40f10721d601f2bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -266,8 +266,8 @@ importers: specifier: workspace:* version: link:../employee-portal-api '@keycloak/keycloak-admin-client': - specifier: 25.0.5 - version: 25.0.5 + specifier: 25.0.6 + version: 25.0.6 '@playwright/test': specifier: 1.46.1 version: 1.46.1 @@ -494,8 +494,8 @@ importers: specifier: 9.0.1 version: 9.0.1 '@keycloak/keycloak-admin-client': - specifier: 25.0.5 - version: 25.0.5 + specifier: 25.0.6 + version: 25.0.6 '@types/k6': specifier: 0.53.2 version: 0.53.2 @@ -1713,8 +1713,8 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@keycloak/keycloak-admin-client@25.0.5': - resolution: {integrity: sha512-IpCKVyBbDm3oIEImszXRQFA3IefrdIxCaPykwNjlFlvfZ6E+Ma7GyNXlT3oukPlAeCgPG+zM/sHcooWZ6ZUl/Q==} + '@keycloak/keycloak-admin-client@25.0.6': + resolution: {integrity: sha512-rUvo6L0aT9+y/R2wFhDKb+lRD5rwj36XwnIGIbmC2HeQVfgroYB5u/79yc/Mo0inBFNIG8VuiwjRzU878fRE0Q==} engines: {node: '>=18'} '@matrix-org/matrix-sdk-crypto-wasm@7.0.0': @@ -7224,7 +7224,7 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@keycloak/keycloak-admin-client@25.0.5': + '@keycloak/keycloak-admin-client@25.0.6': dependencies: camelize-ts: 3.0.0 url-join: 5.0.0 @@ -9078,7 +9078,7 @@ snapshots: '@typescript-eslint/parser': 8.5.0(eslint@8.57.1)(typescript@5.6.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-import: 2.30.0(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.1) eslint-plugin-react: 7.34.2(eslint@8.57.1) @@ -9102,13 +9102,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.5 enhanced-resolve: 5.17.0 eslint: 8.57.1 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-bun-module: 1.1.0 @@ -9162,14 +9162,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.8.1(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.5.0(eslint@8.57.1)(typescript@5.6.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.5.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.6.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color diff --git a/publiccode.yml b/publiccode.yml index 106c984abb8b582d0d3525e01618f9ed6643ec55..99f4966a0564839156364d101418090d7d1bc133 100644 --- a/publiccode.yml +++ b/publiccode.yml @@ -69,5 +69,5 @@ platforms: releaseDate: '2024-10-01' softwareType: standalone/web softwareVersion: '1.0' -url: 'https://gitlab.opencode.de/ga-lotse/ga-lotse.git' +url: 'https://gitlab.opencode.de/ga-lotse/ga-lotse-code.git' landingUrl: 'https://gitlab.opencode.de/ga-lotse' \ No newline at end of file diff --git a/reverse-proxy/citizen-portal.conf b/reverse-proxy/citizen-portal.conf index 660b9ddc6331c43c386ca261c6f5cbfb989346fa..fb70cebd76a43ee0ffba374ba5659e14e1bdf8a2 100644 --- a/reverse-proxy/citizen-portal.conf +++ b/reverse-proxy/citizen-portal.conf @@ -77,8 +77,11 @@ server { } # No authentication needed for security.txt - location /security.txt { - proxy_pass http://host.docker.internal:8080/department/security-txt; + location = /security.txt { + proxy_pass http://host.docker.internal:8080/department/security-txt; + } + location = /pgp-key.txt { + proxy_pass http://host.docker.internal:8080/department/security-txt-public-key; } # No authentication for static stuff diff --git a/reverse-proxy/employee-portal.conf b/reverse-proxy/employee-portal.conf index 494aa73f9436b7fbc4ec28ef1bd03eadbe3ee507..154852e98a74f93ff951ccda1eb2896fe91d3bbc 100644 --- a/reverse-proxy/employee-portal.conf +++ b/reverse-proxy/employee-portal.conf @@ -106,6 +106,9 @@ server { location = /security.txt { proxy_pass http://host.docker.internal:8080/department/security-txt; } + location = /pgp-key.txt { + proxy_pass http://host.docker.internal:8080/department/security-txt-public-key; + } location / { include auth_request.conf;