Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLeitwolf112026-09-28 01:10:53 +0300
committerLeitwolf112026-09-28 01:10:53 +0300
commit252ca8eae71faf1e4e4d00dc7a0489998df12f04 (patch)
treea84a3b6bfe6ab817bc8f433b94a100c2e3f477a9
parentb38ddd55913442da31b6277724a391af2bcc77bc (diff)
downloadwebsite-252ca8eae71faf1e4e4d00dc7a0489998df12f04.tar.gz
Pin website dependencies and isolate Codecov credentials
-rw-r--r--.github/workflows/ci.yml77
-rw-r--r--.github/workflows/codeql.yml13
-rw-r--r--Documents/OPERATIONS.md19
-rw-r--r--REUSE.toml15
-rw-r--r--backend/build.gradle.kts5
-rw-r--r--backend/gradle.lockfile126
-rw-r--r--backend/gradle/verification-metadata.xml1718
-rw-r--r--frontend/tests/site-integrity.test.mjs85
8 files changed, 2027 insertions, 31 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 91eeeea..ce6e207 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,7 +10,6 @@ on:
permissions:
contents: read
- id-token: write
concurrency:
group: website-${{ github.ref }}
@@ -21,26 +20,26 @@ jobs:
runs-on: windows-latest
timeout-minutes: 15
steps:
- - uses: actions/checkout@v7
- - uses: actions/setup-node@v7
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24
cache: npm
cache-dependency-path: frontend/package-lock.json
- run: npm ci
working-directory: frontend
- - run: npm audit --audit-level=high
+ - run: npm audit --audit-level=moderate
working-directory: frontend
- run: npm run check
working-directory: frontend
- run: npm run test:coverage
working-directory: frontend
- - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
- use_oidc: true
- files: frontend/coverage/lcov.info
- flags: website-frontend
- fail_ci_if_error: true
+ name: website-frontend-coverage
+ path: frontend/coverage/lcov.info
+ if-no-files-found: error
+ retention-days: 1
- run: npm run format:check
working-directory: frontend
- run: npm run build
@@ -50,21 +49,65 @@ jobs:
runs-on: macos-latest
timeout-minutes: 25
steps:
- - uses: actions/checkout@v7
- - uses: actions/setup-java@v6
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ - uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1
with:
distribution: temurin
- java-version: '25'
- - uses: gradle/actions/setup-gradle@v6
+ java-version: "25"
+ - uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0
with:
- gradle-version: '9.6.0'
+ gradle-version: "9.6.0"
cache-provider: basic
- run: gradle test jacocoTestReport bootJar --no-daemon
working-directory: backend
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: website-backend-coverage
+ path: backend/build/reports/jacoco/test/jacocoTestReport.xml
+ if-no-files-found: error
+ retention-days: 1
+
+ frontend-coverage:
+ # Fork PRs cannot receive the OIDC token required for Codecov uploads.
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
+ needs: frontend
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ permissions:
+ contents: read
+ id-token: write
+ steps:
+ # Keep OIDC-capable jobs isolated from package install/build scripts.
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: website-frontend-coverage
+ path: coverage/frontend
+ - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
+ with:
+ use_oidc: true
+ files: coverage/frontend/lcov.info
+ flags: website-frontend
+ fail_ci_if_error: true
+
+ backend-coverage:
+ # Fork PRs cannot receive the OIDC token required for Codecov uploads.
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
+ needs: backend
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ permissions:
+ contents: read
+ id-token: write
+ steps:
+ # Keep OIDC-capable jobs isolated from Gradle build scripts.
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: website-backend-coverage
+ path: coverage/backend
- uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
use_oidc: true
- files: backend/build/reports/jacoco/test/jacocoTestReport.xml
+ files: coverage/backend/jacocoTestReport.xml
flags: website-backend
fail_ci_if_error: true
@@ -73,5 +116,5 @@ jobs:
runs-on: windows-latest
timeout-minutes: 10
steps:
- - uses: actions/checkout@v7
- - uses: actions/dependency-review-action@v4
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ - uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 2088ed7..0b29f44 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -7,7 +7,7 @@ on:
branches: [main]
pull_request:
schedule:
- - cron: '43 4 * * 1'
+ - cron: "43 4 * * 1"
permissions:
actions: read
contents: read
@@ -28,16 +28,16 @@ jobs:
- language: java-kotlin
build_mode: manual
steps:
- - uses: actions/checkout@v7
- - uses: actions/setup-java@v6
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ - uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6 # v6.0.1
if: matrix.language == 'java-kotlin'
with:
distribution: temurin
- java-version: '25'
- - uses: gradle/actions/setup-gradle@v6
+ java-version: "25"
+ - uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0
if: matrix.language == 'java-kotlin'
with:
- gradle-version: '9.6.0'
+ gradle-version: "9.6.0"
- uses: github/codeql-action/init@7999b86c43a865dc79d8923397f35af22de63401 # v4
with:
languages: ${{ matrix.language }}
@@ -51,4 +51,3 @@ jobs:
- uses: github/codeql-action/analyze@7999b86c43a865dc79d8923397f35af22de63401 # v4
with:
category: /language:${{ matrix.language }}
-
diff --git a/Documents/OPERATIONS.md b/Documents/OPERATIONS.md
index 830e8a8..96baa57 100644
--- a/Documents/OPERATIONS.md
+++ b/Documents/OPERATIONS.md
@@ -21,8 +21,10 @@ compatibility, but it does not make package functions part of this website.
Do not use a catch-all `/api/` proxy for this service. The production Nginx
configuration proxies exactly `/api/v1/site`; other `/api/` paths return 404.
-The Spring process listens only on `127.0.0.1:5080`. Its `/health` endpoint is
-for local process checks, not an advertised public route.
+The Spring process binds only to `127.0.0.1`. Local runs default to port 5080;
+the checked-in systemd unit sets `PORT=5086`, matching the future Nginx proxy.
+Its `/health` endpoint is for local process checks, not an advertised public
+route.
## Local gates
@@ -42,6 +44,19 @@ Run the backend gates from `backend/` with Temurin JDK 25:
gradle test bootJar --no-daemon
```
+The backend checks in Gradle dependency locks and SHA-256 verification metadata
+to keep transitive versions and downloaded artifacts stable. When intentionally
+updating dependencies, run these commands from `backend/`, review both generated
+files, then rerun the ordinary backend gates:
+
+```text
+gradle dependencies --write-locks --no-daemon
+gradle test jacocoTestReport bootJar --write-verification-metadata sha256 --no-daemon
+```
+
+Do not accept a checksum-only change without confirming the artifact version
+and source repository; the checksum is an integrity pin, not a trust review.
+
The frontend tests assert canonical metadata, sitemap membership, asset shape,
forum non-indexing, and the absence of retired site links. The Spring tests
assert site-only API behavior, health, read-only operation, and missing account
diff --git a/REUSE.toml b/REUSE.toml
index e5fd1f9..4662688 100644
--- a/REUSE.toml
+++ b/REUSE.toml
@@ -4,7 +4,20 @@ SPDX-PackageSupplier = "Organization: Progmasoft"
SPDX-PackageDownloadLocation = "https://github.com/Progmasoft/website"
[[annotations]]
-path = ["forum/visual-xsharp.svg", "forum/visual-xsharp-mark.svg", "frontend/.prettierrc.json", "frontend/package-lock.json", "frontend/package.json", "frontend/public/sitemap.xml", "frontend/public/visual-xsharp.svg", "frontend/public/visual-xsharp-mark.svg", "frontend/public/visual-xsharp-social.png", "frontend/tsconfig.json"]
+path = [
+ "backend/gradle.lockfile",
+ "backend/gradle/verification-metadata.xml",
+ "forum/visual-xsharp.svg",
+ "forum/visual-xsharp-mark.svg",
+ "frontend/.prettierrc.json",
+ "frontend/package-lock.json",
+ "frontend/package.json",
+ "frontend/public/sitemap.xml",
+ "frontend/public/visual-xsharp.svg",
+ "frontend/public/visual-xsharp-mark.svg",
+ "frontend/public/visual-xsharp-social.png",
+ "frontend/tsconfig.json",
+]
precedence = "aggregate"
SPDX-FileCopyrightText = "2026 Progmasoft <support@progmasoft.com>"
SPDX-License-Identifier = "AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1"
diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts
index 797983b..0fbc2c0 100644
--- a/backend/build.gradle.kts
+++ b/backend/build.gradle.kts
@@ -13,6 +13,11 @@ version = "1.0.0"
repositories { mavenCentral() }
+dependencyLocking {
+ // Keep transitive versions stable between developer machines and CI runs.
+ lockAllConfigurations()
+}
+
kotlin { jvmToolchain(25) }
dependencies {
diff --git a/backend/gradle.lockfile b/backend/gradle.lockfile
new file mode 100644
index 0000000..2213ea4
--- /dev/null
+++ b/backend/gradle.lockfile
@@ -0,0 +1,126 @@
+# 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.
+# To regenerate this file, run: gradle dependencies --write-locks --no-daemon
+biz.aQute.bnd:biz.aQute.bnd.annotation:7.1.0=compileClasspath,testCompileClasspath
+ch.qos.logback:logback-classic:1.5.38=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+ch.qos.logback:logback-core:1.5.38=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+com.fasterxml.jackson.core:jackson-annotations:2.21=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+com.fasterxml.jackson.core:jackson-core:2.21.5=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+com.fasterxml.jackson.core:jackson-databind:2.21.5=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+com.fasterxml.jackson.module:jackson-module-kotlin:2.21.5=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+com.fasterxml.jackson:jackson-bom:2.21.5=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+com.google.errorprone:error_prone_annotations:2.38.0=compileClasspath,testCompileClasspath
+com.jayway.jsonpath:json-path:2.10.0=testCompileClasspath,testRuntimeClasspath
+com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspath,testRuntimeClasspath
+commons-logging:commons-logging:1.3.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+io.github.java-diff-utils:java-diff-utils:4.12=kotlinInternalAbiValidation
+io.micrometer:micrometer-commons:1.17.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+io.micrometer:micrometer-observation:1.17.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+jakarta.activation:jakarta.activation-api:2.1.4=testCompileClasspath,testRuntimeClasspath
+jakarta.annotation:jakarta.annotation-api:3.0.0=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+jakarta.xml.bind:jakarta.xml.bind-api:4.0.5=testCompileClasspath,testRuntimeClasspath
+net.bytebuddy:byte-buddy-agent:1.18.11=testCompileClasspath,testRuntimeClasspath
+net.bytebuddy:byte-buddy:1.18.11=testCompileClasspath,testRuntimeClasspath
+net.minidev:accessors-smart:2.6.0=testCompileClasspath,testRuntimeClasspath
+net.minidev:json-smart:2.6.0=testCompileClasspath,testRuntimeClasspath
+org.apache.logging.log4j:log4j-api:2.25.5=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.apache.logging.log4j:log4j-to-slf4j:2.25.5=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.apache.tomcat.embed:tomcat-embed-core:11.0.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.apache.tomcat.embed:tomcat-embed-el:11.0.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.apache.tomcat.embed:tomcat-embed-websocket:11.0.24=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath
+org.assertj:assertj-core:3.27.7=testCompileClasspath,testRuntimeClasspath
+org.awaitility:awaitility:4.3.0=testCompileClasspath,testRuntimeClasspath
+org.hamcrest:hamcrest:3.0=testCompileClasspath,testRuntimeClasspath
+org.jacoco:org.jacoco.agent:0.8.15=jacocoAgent,jacocoAnt
+org.jacoco:org.jacoco.ant:0.8.15=jacocoAnt
+org.jacoco:org.jacoco.core:0.8.15=jacocoAnt
+org.jacoco:org.jacoco.report:0.8.15=jacocoAnt
+org.jetbrains.kotlin:abi-tools-api:2.3.21=kotlinInternalAbiValidation
+org.jetbrains.kotlin:abi-tools:2.3.21=kotlinInternalAbiValidation
+org.jetbrains.kotlin:kotlin-allopen-compiler-plugin-embeddable:2.3.21=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
+org.jetbrains.kotlin:kotlin-build-tools-api:2.3.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
+org.jetbrains.kotlin:kotlin-build-tools-compat:2.3.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
+org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.3.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
+org.jetbrains.kotlin:kotlin-build-tools-impl:2.3.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
+org.jetbrains.kotlin:kotlin-compiler-embeddable:2.3.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-compiler-runner:2.3.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
+org.jetbrains.kotlin:kotlin-daemon-client:2.3.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
+org.jetbrains.kotlin:kotlin-daemon-embeddable:2.3.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-klib-abi-reader:2.3.21=kotlinInternalAbiValidation
+org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:2.3.21=kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-metadata-jvm:2.3.21=kotlinInternalAbiValidation
+org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-reflect:2.3.21=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.jetbrains.kotlin:kotlin-script-runtime:2.3.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
+org.jetbrains.kotlin:kotlin-scripting-common:2.3.21=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
+org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.3.21=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
+org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.3.21=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
+org.jetbrains.kotlin:kotlin-scripting-jvm:2.3.21=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
+org.jetbrains.kotlin:kotlin-stdlib:2.3.21=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.jetbrains.kotlin:kotlin-test-junit5:2.3.21=testCompileClasspath,testRuntimeClasspath
+org.jetbrains.kotlin:kotlin-test:2.3.21=testCompileClasspath,testRuntimeClasspath
+org.jetbrains.kotlin:kotlin-tooling-core:2.3.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
+org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
+org.jetbrains:annotations:13.0=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.jspecify:jspecify:1.0.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.junit.jupiter:junit-jupiter-api:6.0.3=testCompileClasspath,testRuntimeClasspath
+org.junit.jupiter:junit-jupiter-engine:6.0.3=testRuntimeClasspath
+org.junit.jupiter:junit-jupiter-params:6.0.3=testCompileClasspath,testRuntimeClasspath
+org.junit.jupiter:junit-jupiter:6.0.3=testCompileClasspath,testRuntimeClasspath
+org.junit.platform:junit-platform-commons:6.0.3=testCompileClasspath,testRuntimeClasspath
+org.junit.platform:junit-platform-engine:6.0.3=testRuntimeClasspath
+org.junit.platform:junit-platform-launcher:6.0.3=testRuntimeClasspath
+org.junit:junit-bom:6.0.3=testCompileClasspath,testRuntimeClasspath
+org.mockito:mockito-core:5.23.0=testCompileClasspath,testRuntimeClasspath
+org.mockito:mockito-junit-jupiter:5.23.0=testCompileClasspath,testRuntimeClasspath
+org.objenesis:objenesis:3.3=testRuntimeClasspath
+org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath
+org.osgi:org.osgi.annotation.bundle:2.0.0=compileClasspath,testCompileClasspath
+org.osgi:org.osgi.annotation.versioning:1.1.2=compileClasspath,testCompileClasspath
+org.osgi:org.osgi.resource:1.0.0=compileClasspath,testCompileClasspath
+org.osgi:org.osgi.service.serviceloader:1.0.0=compileClasspath,testCompileClasspath
+org.ow2.asm:asm-commons:9.10.1=jacocoAnt
+org.ow2.asm:asm-tree:9.10.1=jacocoAnt
+org.ow2.asm:asm:9.10.1=jacocoAnt
+org.ow2.asm:asm:9.7.1=testCompileClasspath,testRuntimeClasspath
+org.skyscreamer:jsonassert:1.5.3=testCompileClasspath,testRuntimeClasspath
+org.slf4j:jul-to-slf4j:2.0.18=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.slf4j:slf4j-api:2.0.18=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-autoconfigure:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-dependencies:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-http-converter:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-jackson:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-resttestclient:4.1.1=testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-servlet:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-starter-jackson-test:4.1.1=testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-starter-jackson:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-starter-logging:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-starter-test:4.1.1=testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-starter-tomcat-runtime:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-starter-tomcat:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-starter-webmvc-test:4.1.1=testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-starter-webmvc:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-starter:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-test-autoconfigure:4.1.1=testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-test:4.1.1=testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-tomcat:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-web-server:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-webmvc-test:4.1.1=testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot-webmvc:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework.boot:spring-boot:4.1.1=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework:spring-aop:7.0.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework:spring-beans:7.0.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework:spring-context:7.0.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework:spring-core:7.0.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework:spring-expression:7.0.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework:spring-test:7.0.9=testCompileClasspath,testRuntimeClasspath
+org.springframework:spring-web:7.0.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.springframework:spring-webmvc:7.0.9=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.xmlunit:xmlunit-core:2.11.0=testCompileClasspath,testRuntimeClasspath
+org.yaml:snakeyaml:2.6=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+tools.jackson.core:jackson-core:3.1.5=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+tools.jackson.core:jackson-databind:3.1.5=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+tools.jackson:jackson-bom:3.1.5=compileClasspath,productionRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+empty=annotationProcessor,developmentOnly,implementationDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,testAndDevelopmentOnly,testAnnotationProcessor,testImplementationDependenciesMetadata,testKotlinScriptDefExtensions
diff --git a/backend/gradle/verification-metadata.xml b/backend/gradle/verification-metadata.xml
new file mode 100644
index 0000000..f8c2fb5
--- /dev/null
+++ b/backend/gradle/verification-metadata.xml
@@ -0,0 +1,1718 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<verification-metadata xmlns="https://schema.gradle.org/dependency-verification" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://schema.gradle.org/dependency-verification https://schema.gradle.org/dependency-verification/dependency-verification-1.3.xsd">
+ <configuration>
+ <verify-metadata>true</verify-metadata>
+ <verify-signatures>false</verify-signatures>
+ </configuration>
+ <components>
+ <component group="biz.aQute.bnd" name="biz.aQute.bnd.annotation" version="7.1.0">
+ <artifact name="biz.aQute.bnd.annotation-7.1.0.jar">
+ <sha256 value="f69c2de3a695c113d125ac8053c92a680a3ce9d02ea25845095cf2d4626a7663" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="biz.aQute.bnd.annotation-7.1.0.pom">
+ <sha256 value="5822df49183df922ba59ae773a2d8cceb86ae1e20f41f19873131dd182494f7a" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="ch.qos.logback" name="logback-classic" version="1.5.38">
+ <artifact name="logback-classic-1.5.38.jar">
+ <sha256 value="afb439c61fa287c9e1925523b13baab03617e724406a389d48b61c2c3e46b700" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="logback-classic-1.5.38.pom">
+ <sha256 value="63313f843b669c60255e66f2c52a9c1d3af3787009d9f389159e35a691b63857" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="ch.qos.logback" name="logback-core" version="1.5.38">
+ <artifact name="logback-core-1.5.38.jar">
+ <sha256 value="a855a0fc97b1d06f4efb1c3bba5ebd0eb508d8b58e68e89e4bbc23a85135c883" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="logback-core-1.5.38.pom">
+ <sha256 value="dba1707f025202fe344052163c3419a0f03d056777ac5c346175e5523c937d60" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="ch.qos.logback" name="logback-parent" version="1.5.38">
+ <artifact name="logback-parent-1.5.38.pom">
+ <sha256 value="2bce3a61a6449adb9a0722e1c0c1e391533880ba02916d3df83208999aea6c66" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.fasterxml" name="oss-parent" version="75">
+ <artifact name="oss-parent-75.pom">
+ <sha256 value="fcbbf1c18c9047e6917d384f2064e21b42a58fc85fb0523a9e2e015eff7c619d" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.fasterxml" name="oss-parent" version="79">
+ <artifact name="oss-parent-79.pom">
+ <sha256 value="9206b7dd67fb138036576c3dfca947a2a8f3e2c4d2d9c1f2d1dea519b3a4dae1" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.fasterxml.jackson" name="jackson-bom" version="2.21.5">
+ <artifact name="jackson-bom-2.21.5.pom">
+ <sha256 value="57fe22dec659de0655357fad0582ef7c8b2fe5a8906a6f1ff1bcbbd1e4554846" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.fasterxml.jackson" name="jackson-parent" version="2.21">
+ <artifact name="jackson-parent-2.21.pom">
+ <sha256 value="3851df627faeb46887b956104630b74a8bbb5f7de22e974cf15982e20e0373de" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.fasterxml.jackson.core" name="jackson-annotations" version="2.21">
+ <artifact name="jackson-annotations-2.21.jar">
+ <sha256 value="53ca085f4a150f703f49e1aabd935bd03b43e1ea3d55d135438292af22cef56b" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="jackson-annotations-2.21.module">
+ <sha256 value="cae8ffecec3328b6ecbb138e274218f2fe1c7729a0e824da559268810095ad44" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.fasterxml.jackson.core" name="jackson-core" version="2.21.5">
+ <artifact name="jackson-core-2.21.5.jar">
+ <sha256 value="b64b5874162b503a0e58a8f7758266e8dd9f91bf49e3a59ae0b5f47589a231b7" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="jackson-core-2.21.5.module">
+ <sha256 value="de113f4531def50feb12be04e7074a8f76f5f3ef290cf886b90086a4e274530f" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.fasterxml.jackson.core" name="jackson-databind" version="2.21.5">
+ <artifact name="jackson-databind-2.21.5.jar">
+ <sha256 value="507418c0fafd38b2b2cfb704521630da613a8e4cc8381195a6f418017883e2c0" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="jackson-databind-2.21.5.module">
+ <sha256 value="920e2a0211a31f54d2e7e4effdc580d02c3412a6fefdb632a8054e60c4758381" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.fasterxml.jackson.module" name="jackson-module-kotlin" version="2.21.5">
+ <artifact name="jackson-module-kotlin-2.21.5.jar">
+ <sha256 value="6f45bbe434458d2ad1f5ea16c6abf67e7abea374b2c9ae5689cf4dd27c16c8b9" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="jackson-module-kotlin-2.21.5.module">
+ <sha256 value="1a9f780447658ddb47ec9d7dcc60979aab2a5b25f0e902946853dd292bd88581" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.google.code.findbugs" name="jsr305" version="3.0.2">
+ <artifact name="jsr305-3.0.2.jar">
+ <sha256 value="766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="jsr305-3.0.2.pom">
+ <sha256 value="19889dbdf1b254b2601a5ee645b8147a974644882297684c798afe5d63d78dfe" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.google.code.gson" name="gson" version="2.11.0">
+ <artifact name="gson-2.11.0.jar">
+ <sha256 value="57928d6e5a6edeb2abd3770a8f95ba44dce45f3b23b7a9dc2b309c581552a78b" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="gson-2.11.0.pom">
+ <sha256 value="c0e547bea998888e6e25c5886a90e762272bc88b5275343dd2c05ded6ca2e360" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.google.code.gson" name="gson-parent" version="2.11.0">
+ <artifact name="gson-parent-2.11.0.pom">
+ <sha256 value="8acb1f3b72a6f026916ac0735bad9aab0293d527edb7b365327def13a9367b7a" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.google.errorprone" name="error_prone_annotations" version="2.27.0">
+ <artifact name="error_prone_annotations-2.27.0.jar">
+ <sha256 value="24c923372c58e35d0b9f16a028929bb9aedc77521867c274f2bd0735df5ba1f5" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="error_prone_annotations-2.27.0.pom">
+ <sha256 value="4ca5a35d61235e16549ac346d1e34551cdf0fe27e84aa57e03cbeb255ea4e5da" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.google.errorprone" name="error_prone_annotations" version="2.38.0">
+ <artifact name="error_prone_annotations-2.38.0.jar">
+ <sha256 value="6661d5335090a5fc61dd869d2095bc6c1e2156e3aa47a6e4ababdf64c99a7889" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="error_prone_annotations-2.38.0.pom">
+ <sha256 value="3007bef8aff3ae8ea12d81c3feacb4f15979b2cf5c3e38fc9189a98dea141167" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.google.errorprone" name="error_prone_parent" version="2.27.0">
+ <artifact name="error_prone_parent-2.27.0.pom">
+ <sha256 value="fa81829d049559df6927f9c9a6fd6bbd09f8b50e6d4736ae72c8300b6c3d7654" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.google.errorprone" name="error_prone_parent" version="2.38.0">
+ <artifact name="error_prone_parent-2.38.0.pom">
+ <sha256 value="e62458a6a3e63081bc7c57b3c0fac9f04f76ce32f606532db69fe2b3d47b934c" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.google.protobuf" name="protobuf-bom" version="4.35.1">
+ <artifact name="protobuf-bom-4.35.1.pom">
+ <sha256 value="08eec56bd1611b40c471f4b6146d0a67bc154b35b55e0014e872a0d2b74373d5" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.jayway.jsonpath" name="json-path" version="2.10.0">
+ <artifact name="json-path-2.10.0.jar">
+ <sha256 value="890daa95dd3892d34d9fabc27cd5153656e6f369358625c88f4dc7b79cbd6c5a" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="json-path-2.10.0.module">
+ <sha256 value="66f1b968725750c4dce9da7d7b3a43150384cf426ca270c608910fa365a52ac2" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.querydsl" name="querydsl-bom" version="5.1.0">
+ <artifact name="querydsl-bom-5.1.0.pom">
+ <sha256 value="8853dce132c9ece4c295c7f4d4f3c2832eee0d7d44930870c0666fa72043ca56" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="com.vaadin.external.google" name="android-json" version="0.0.20131108.vaadin1">
+ <artifact name="android-json-0.0.20131108.vaadin1.jar">
+ <sha256 value="dfb7bae2f404cfe0b72b4d23944698cb716b7665171812a0a4d0f5926c0fac79" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="android-json-0.0.20131108.vaadin1.pom">
+ <sha256 value="2ff6c17d9c060b89cd7ef18fa480ae2446eba86855a633f3892837fc3b848fef" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="commons-codec" name="commons-codec" version="1.17.1">
+ <artifact name="commons-codec-1.17.1.jar">
+ <sha256 value="f9f6cb103f2ddc3c99a9d80ada2ae7bf0685111fd6bffccb72033d1da4e6ff23" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="commons-codec-1.17.1.pom">
+ <sha256 value="7fa0db4d8150daf932958b8aea89ee24abb4d18e2316a5de535278fc131512a0" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="commons-io" name="commons-io" version="2.16.1">
+ <artifact name="commons-io-2.16.1.jar">
+ <sha256 value="f41f7baacd716896447ace9758621f62c1c6b0a91d89acee488da26fc477c84f" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="commons-io-2.16.1.pom">
+ <sha256 value="5777d292251c7895c04a4c57015683ec3b353a12486c9b3e7178e9b0b3c38fff" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="commons-logging" name="commons-logging" version="1.3.5">
+ <artifact name="commons-logging-1.3.5.jar">
+ <sha256 value="6d7a744e4027649fbb50895df9497d109f98c766a637062fe8d2eabbb3140ba4" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="commons-logging-1.3.5.pom">
+ <sha256 value="ccf4a30346f5027b9496abd56290ac26d159abf2be64df1265611dc9400b9d68" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="commons-logging" name="commons-logging" version="1.3.6">
+ <artifact name="commons-logging-1.3.6.jar">
+ <sha256 value="f8ead8943401081dea0aa824b5b1ba40a0e4ed297a572a0f02258150a0b62357" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="commons-logging-1.3.6.pom">
+ <sha256 value="49fc185139bdd0c6c4adf440721e3279cb5342906bcd01a7a89399ceeaa78e85" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="io.github.java-diff-utils" name="java-diff-utils" version="4.12">
+ <artifact name="java-diff-utils-4.12.jar">
+ <sha256 value="9990a2039778f6b4cc94790141c2868864eacee0620c6c459451121a901cd5b5" origin="Generated by Gradle"/>
+ </artifact>
+ <artifact name="java-diff-utils-4.12.pom">
+ <sha256 value="c26e097edc8ec6805d1319817d23d4e496cc1015cc55dc5202112d8f6a9165fc" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="io.github.java-diff-utils" name="java-diff-utils-parent" version="4.12">
+ <artifact name="java-diff-utils-parent-4.12.pom">
+ <sha256 value="d811cf9f118cc2cad130c9427ad55c174d4c0a6f1a00ac1ae1c9bcbec5c44b19" origin="Generated by Gradle"/>
+ </artifact>
+ </component>
+ <component group="io.grpc" name="grpc-bom" version="1.83.1">
+ <artifact name="grpc-bom-1.83.1.pom">
+ <sha256 value="58cc1c0c0e6dc3aa28a6b8f6c8cc1cbdbdc47843cfba282d07f694c2b1af4f8b" origin="Generated by Gradle"/>
+ </artifact