diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 38975fd5..367ce0d0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -36,6 +36,10 @@ updates: labels: - portfolio-maintenance - needs-runtime-smoke + ignore: + - dependency-name: typescript + update-types: + - version-update:semver-major groups: frontend-platform: patterns: diff --git a/.github/workflows/ai-eval.yml b/.github/workflows/ai-eval.yml index c287c3aa..ae672881 100644 --- a/.github/workflows/ai-eval.yml +++ b/.github/workflows/ai-eval.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Validate compose file run: docker compose config --quiet @@ -27,7 +27,7 @@ jobs: - name: Upload AI eval report if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: ai-eval-summary path: reports/ai/eval-summary.json @@ -39,7 +39,7 @@ jobs: - name: Store compose logs if: failure() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: compose-ai-eval-log path: compose-ai-eval.log diff --git a/.github/workflows/api-smoke.yml b/.github/workflows/api-smoke.yml index 6cf1a719..55d5d85b 100644 --- a/.github/workflows/api-smoke.yml +++ b/.github/workflows/api-smoke.yml @@ -15,7 +15,7 @@ jobs: timeout-minutes: 35 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Validate compose file run: docker compose config --quiet @@ -30,7 +30,7 @@ jobs: - name: Store compose logs if: failure() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: compose-api-smoke-log path: compose-api-smoke.log diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 364d1be1..64f88811 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up Java 21 uses: actions/setup-java@v5 @@ -77,7 +77,7 @@ jobs: - name: Upload test reports on failure if: failure() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: test-reports path: | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 19fb5a20..ede4fa27 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -29,7 +29,7 @@ jobs: - javascript-typescript steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up Java 21 if: matrix.language == 'java-kotlin' diff --git a/.github/workflows/dependabot-curation.yml b/.github/workflows/dependabot-curation.yml index 560a5bf4..b8061b8d 100644 --- a/.github/workflows/dependabot-curation.yml +++ b/.github/workflows/dependabot-curation.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Run curation shell: pwsh @@ -55,7 +55,7 @@ jobs: - name: Upload curation reports if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: dependabot-curation-reports path: | diff --git a/.github/workflows/dependency-maintenance.yml b/.github/workflows/dependency-maintenance.yml index c0c8db8e..f6006d0f 100644 --- a/.github/workflows/dependency-maintenance.yml +++ b/.github/workflows/dependency-maintenance.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Generate inventory shell: pwsh @@ -26,7 +26,7 @@ jobs: run: ./scripts/dependabot-inventory.ps1 - name: Upload inventory - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: dependabot-inventory path: reports/dependabot/ diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 35e4c363..4bb44ba3 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ec0dc452..834bc24f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Validate portfolio documentation shell: pwsh diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 67c184fb..95e16ce3 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up Node.js uses: actions/setup-node@v6 @@ -54,7 +54,7 @@ jobs: - name: Upload Playwright preview report if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: playwright-preview-report path: | @@ -70,7 +70,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up Node.js uses: actions/setup-node@v6 @@ -93,7 +93,7 @@ jobs: - name: Upload Playwright report if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: playwright-report path: frontend/playwright-report diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 4e71dd9c..2f565e6b 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -28,7 +28,7 @@ jobs: timeout-minutes: 40 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Start stack and validate business flow shell: pwsh @@ -45,7 +45,7 @@ jobs: - name: Upload k6 summary if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: k6-role-based-suite-summary path: reports/k6/role-based-suite-summary.json @@ -57,7 +57,7 @@ jobs: - name: Store compose logs if: failure() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: compose-performance-smoke-log path: compose-performance-smoke.log diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3ea1726e..950238a1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 @@ -168,7 +168,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Create release from notes env: diff --git a/.github/workflows/repository-governance.yml b/.github/workflows/repository-governance.yml index ded743e2..fd3800bd 100644 --- a/.github/workflows/repository-governance.yml +++ b/.github/workflows/repository-governance.yml @@ -27,7 +27,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Dry-run repository governance if: ${{ inputs.mode == 'dry-run' }} @@ -92,7 +92,7 @@ jobs: - name: Upload governance reports if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: repository-governance-reports path: | diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index b4003cb2..c601727c 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: persist-credentials: false @@ -30,7 +30,7 @@ jobs: run: mkdir -p security-reports - name: Run OpenSSF Scorecard - uses: ossf/scorecard-action@v2.4.0 + uses: ossf/scorecard-action@v2.4.3 with: results_file: security-reports/scorecard.sarif results_format: sarif @@ -38,7 +38,7 @@ jobs: - name: Upload Scorecard report if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: openssf-scorecard-report path: security-reports/scorecard.sarif diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 3552b836..36eb7406 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -22,12 +22,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: fetch-depth: 0 - name: Scan repository for secrets - uses: gitleaks/gitleaks-action@v2 + uses: gitleaks/gitleaks-action@v3 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITLEAKS_CONFIG: .gitleaks.toml @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Prepare reports directory run: mkdir -p security-reports @@ -56,7 +56,7 @@ jobs: - name: Upload Trivy filesystem report if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: trivy-filesystem-report path: security-reports/trivy-fs.txt @@ -70,7 +70,7 @@ jobs: actions: read steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Prepare reports directory run: mkdir -p security-reports @@ -83,7 +83,7 @@ jobs: output-file: security-reports/devhire-cloud-sbom.cdx.json - name: Upload SBOM - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: devhire-cloud-sbom path: security-reports/devhire-cloud-sbom.cdx.json @@ -94,7 +94,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Review dependency changes uses: actions/dependency-review-action@v5 @@ -116,7 +116,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up Java 21 uses: actions/setup-java@v5 @@ -150,7 +150,7 @@ jobs: - frontend steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 @@ -206,7 +206,7 @@ jobs: - name: Upload image scan report if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: trivy-image-${{ matrix.service }} path: security-reports/trivy-image-${{ matrix.service }}.txt diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index bb999498..86c080f8 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -56,7 +56,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Terraform fmt validate lint and config scan shell: pwsh diff --git a/README.md b/README.md index e60bb0c4..5908ac04 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Terraform](https://github.com/JasonTM17/DevHire_Cloud_Spring_Microservices/actions/workflows/terraform.yml/badge.svg)](https://github.com/JasonTM17/DevHire_Cloud_Spring_Microservices/actions/workflows/terraform.yml) [![Docs](https://github.com/JasonTM17/DevHire_Cloud_Spring_Microservices/actions/workflows/docs.yml/badge.svg)](https://github.com/JasonTM17/DevHire_Cloud_Spring_Microservices/actions/workflows/docs.yml) -DevHire Cloud is a production-engineering portfolio for a recruitment platform: Java 21, Spring Boot 3.5, Next.js, Kafka, OpenSearch, PostgreSQL, Redis, Docker, Kubernetes, Terraform, and a controlled Claude Haiku AI assistant. The repository is written for senior review: it emphasizes service boundaries, owned data, event reliability, observability, security, CI/CD, cloud readiness, and evidence that can be checked without trusting the README. +DevHire Cloud is a Java, systems, and DevOps learning project for a recruitment platform: Java 21, Spring Boot 4.0, Next.js, Kafka, OpenSearch, PostgreSQL, Redis, Docker, Kubernetes, Terraform, and a controlled Claude Haiku AI assistant. The repository documents service boundaries, owned data, event reliability, observability, security, CI/CD, and cloud-readiness evidence so reviewers can verify each claim against the code and supporting records. ## 30-Second Reviewer Brief @@ -26,7 +26,7 @@ DevHire Cloud is a production-engineering portfolio for a recruitment platform: | Current development cycle | `0.6.0-SNAPSHOT` release cut; next snapshot bump is a post-release maintenance step | | v0.6 Stitch app | Merged into `master`; Code Assessment Studio is the flagship candidate grading, employer review, and admin health workflow | | Default branch | `master`, protected and PR-governed | -| Dependabot queue | 0 open Dependabot PRs after the 2026-05-14 zero-noise apply; 20 stale/behind/risky PRs were commented, closed, and their remote branches pruned; no dependency PR was force-merged into the release | +| Dependency updates | [View the current Dependabot queue](https://github.com/JasonTM17/DevHire_Cloud_Spring_Microservices/pulls?q=is%3Apr+is%3Aopen+author%3Aapp%2Fdependabot); maintenance policy is documented in [docs/dependency-maintenance.md](docs/dependency-maintenance.md). | | v1 status | Roadmap and acceptance checklist only, not a released tag | ## Reviewer Quick Links @@ -48,6 +48,29 @@ DevHire Cloud is a production-engineering portfolio for a recruitment platform: | Cloud readiness | [docs/cloud-readiness-review.md](docs/cloud-readiness-review.md) | | Production scorecard | [docs/production-engineering-scorecard.md](docs/production-engineering-scorecard.md) | +### Simplified system topology + +This reviewer map groups related services for readability; it is not a complete protocol or event-edge diagram. + +```mermaid +flowchart LR + UI["Next.js frontend"] --> GW["Spring Cloud Gateway"] + GW --> ID["Auth + User"] + GW --> HIRE["Company + Job + Application"] + GW --> OPS["Notification + Audit"] + GW --> AI["Claude AI service"] + HIRE --> RUNNER["Assessment runner"] + HIRE <--> KAFKA[("Kafka + outbox")] + ID --> PG[("Service-owned PostgreSQL")] + HIRE --> PG + OPS --> PG + AI --> PG + HIRE --> SEARCH[("OpenSearch")] + ID --> REDIS[("Redis")] +``` + +[Review the detailed service boundaries and event flows](docs/architecture.md). + ## Architecture and Operations Proof | Layer | Proof in this repository | @@ -182,4 +205,4 @@ The full visual evidence set is machine-checked in [docs/evidence-manifest.json] ## Honest Scope -DevHire Cloud is a production-engineering portfolio, not a claim of live customer traffic. It does not claim external penetration testing, a production AWS account, or real customer data. Secrets are not committed; cloud apply remains a separate, credentialed operation. +DevHire Cloud is a learning project that practices production-engineering patterns, not a claim of live customer traffic. It does not claim external penetration testing, a production AWS account, or real customer data. Secrets are not committed; cloud apply remains a separate, credentialed operation. diff --git a/ai-service/Dockerfile b/ai-service/Dockerfile index 29e8aefb..aa9b59bf 100644 --- a/ai-service/Dockerfile +++ b/ai-service/Dockerfile @@ -1,4 +1,4 @@ -FROM maven:3.9.12-eclipse-temurin-21 AS build +FROM maven:3.9.14-eclipse-temurin-25 AS build WORKDIR /workspace ARG SERVICE_NAME=ai-service COPY pom.xml . @@ -17,7 +17,7 @@ COPY common-lib/src common-lib/src COPY ${SERVICE_NAME}/src ${SERVICE_NAME}/src RUN mvn -B -T1 -pl ${SERVICE_NAME} -am package -DskipTests -FROM eclipse-temurin:21-jre-alpine +FROM eclipse-temurin:25-jre-alpine ARG SERVICE_NAME=ai-service ARG BUILD_VERSION=0.4.0-SNAPSHOT ARG VCS_REF=local diff --git a/ai-service/pom.xml b/ai-service/pom.xml index 651fdcf3..676119a1 100644 --- a/ai-service/pom.xml +++ b/ai-service/pom.xml @@ -42,12 +42,12 @@ spring-boot-starter-jdbc - org.springframework.kafka - spring-kafka + org.springframework.boot + spring-boot-starter-kafka - org.flywaydb - flyway-core + org.springframework.boot + spring-boot-starter-flyway org.flywaydb @@ -84,14 +84,24 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-jdbc-test + test + + + org.springframework.boot + spring-boot-starter-flyway-test + test + org.testcontainers - postgresql + testcontainers-postgresql test org.testcontainers - junit-jupiter + testcontainers-junit-jupiter test diff --git a/ai-service/src/test/java/com/devhire/ai/repository/AiConversationRepositoryIT.java b/ai-service/src/test/java/com/devhire/ai/repository/AiConversationRepositoryIT.java index 103b57ba..ea60d2c6 100644 --- a/ai-service/src/test/java/com/devhire/ai/repository/AiConversationRepositoryIT.java +++ b/ai-service/src/test/java/com/devhire/ai/repository/AiConversationRepositoryIT.java @@ -6,13 +6,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase; +import org.springframework.boot.jdbc.test.autoconfigure.JdbcTest; import org.springframework.context.annotation.Import; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.postgresql.PostgreSQLContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -26,7 +26,7 @@ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class AiConversationRepositoryIT { @Container - static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>("postgres:17-alpine"); + static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer("postgres:17-alpine"); @DynamicPropertySource static void datasource(DynamicPropertyRegistry registry) { diff --git a/api-gateway/Dockerfile b/api-gateway/Dockerfile index 0064b1f2..10fade39 100644 --- a/api-gateway/Dockerfile +++ b/api-gateway/Dockerfile @@ -1,4 +1,4 @@ -FROM maven:3.9.12-eclipse-temurin-21 AS build +FROM maven:3.9.14-eclipse-temurin-25 AS build WORKDIR /workspace ARG SERVICE_NAME=api-gateway COPY pom.xml . @@ -17,7 +17,7 @@ COPY common-lib/src common-lib/src COPY ${SERVICE_NAME}/src ${SERVICE_NAME}/src RUN mvn -B -T1 -pl ${SERVICE_NAME} -am package -DskipTests -FROM eclipse-temurin:21-jre-alpine +FROM eclipse-temurin:25-jre-alpine ARG SERVICE_NAME=api-gateway ARG BUILD_VERSION=0.4.0-SNAPSHOT ARG VCS_REF=local diff --git a/api-gateway/src/main/java/com/devhire/gateway/error/GatewayExceptionHandler.java b/api-gateway/src/main/java/com/devhire/gateway/error/GatewayExceptionHandler.java index bf0fca13..93d6d63a 100644 --- a/api-gateway/src/main/java/com/devhire/gateway/error/GatewayExceptionHandler.java +++ b/api-gateway/src/main/java/com/devhire/gateway/error/GatewayExceptionHandler.java @@ -1,7 +1,7 @@ package com.devhire.gateway.error; import com.devhire.common.error.ErrorCode; -import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.boot.webflux.error.ErrorWebExceptionHandler; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; diff --git a/api-gateway/src/test/java/com/devhire/gateway/security/JwtAuthenticationGatewayFilterTest.java b/api-gateway/src/test/java/com/devhire/gateway/security/JwtAuthenticationGatewayFilterTest.java index 6ded9ec9..e2bc8345 100644 --- a/api-gateway/src/test/java/com/devhire/gateway/security/JwtAuthenticationGatewayFilterTest.java +++ b/api-gateway/src/test/java/com/devhire/gateway/security/JwtAuthenticationGatewayFilterTest.java @@ -85,7 +85,7 @@ void publicAuthRouteStripsSpoofedIdentityHeaders() { filter.filter(exchange, chain).block(); - assertThat(downstreamExchange.get().getRequest().getHeaders()).doesNotContainKey(AppHeaders.USER_ID); + assertThat(downstreamExchange.get().getRequest().getHeaders().containsHeader(AppHeaders.USER_ID)).isFalse(); verifyNoInteractions(redisTemplate); } @@ -108,8 +108,8 @@ void publicCompanyReadsDoNotRequireJwtButStripSpoofedIdentityHeaders() { filter.filter(exchange, chain).block(); - assertThat(downstreamExchange.get().getRequest().getHeaders()).doesNotContainKey(AppHeaders.USER_ID); - assertThat(downstreamExchange.get().getRequest().getHeaders()).doesNotContainKey(AppHeaders.USER_ROLE); + assertThat(downstreamExchange.get().getRequest().getHeaders().containsHeader(AppHeaders.USER_ID)).isFalse(); + assertThat(downstreamExchange.get().getRequest().getHeaders().containsHeader(AppHeaders.USER_ROLE)).isFalse(); } verifyNoInteractions(redisTemplate); } diff --git a/application-service/Dockerfile b/application-service/Dockerfile index f11918d3..9e47d128 100644 --- a/application-service/Dockerfile +++ b/application-service/Dockerfile @@ -1,4 +1,4 @@ -FROM maven:3.9.12-eclipse-temurin-21 AS build +FROM maven:3.9.14-eclipse-temurin-25 AS build WORKDIR /workspace ARG SERVICE_NAME=application-service COPY pom.xml . @@ -17,7 +17,7 @@ COPY common-lib/src common-lib/src COPY ${SERVICE_NAME}/src ${SERVICE_NAME}/src RUN mvn -B -T1 -pl ${SERVICE_NAME} -am package -DskipTests -FROM eclipse-temurin:21-jre-alpine +FROM eclipse-temurin:25-jre-alpine ARG SERVICE_NAME=application-service ARG BUILD_VERSION=0.4.0-SNAPSHOT ARG VCS_REF=local diff --git a/application-service/pom.xml b/application-service/pom.xml index 2f6bc716..3a42e57a 100644 --- a/application-service/pom.xml +++ b/application-service/pom.xml @@ -17,8 +17,8 @@ org.springframework.bootspring-boot-starter-data-jpa org.springframework.bootspring-boot-starter-actuator org.springframework.cloudspring-cloud-starter-openfeign - org.springframework.kafkaspring-kafka - org.flywaydbflyway-core + org.springframework.bootspring-boot-starter-kafka + org.springframework.bootspring-boot-starter-flyway org.flywaydbflyway-database-postgresql org.postgresqlpostgresqlruntime org.springdocspringdoc-openapi-starter-webmvc-ui${springdoc.version} @@ -26,8 +26,10 @@ io.micrometermicrometer-tracing-bridge-otel io.opentelemetryopentelemetry-exporter-otlp org.springframework.bootspring-boot-starter-testtest - org.testcontainerspostgresqltest - org.testcontainersjunit-jupitertest + org.springframework.bootspring-boot-starter-data-jpa-testtest + org.springframework.bootspring-boot-starter-flyway-testtest + org.testcontainerstestcontainers-postgresqltest + org.testcontainerstestcontainers-junit-jupitertest org.springframework.bootspring-boot-maven-plugin diff --git a/application-service/src/test/java/com/devhire/application/repository/ApplicationRepositoryIT.java b/application-service/src/test/java/com/devhire/application/repository/ApplicationRepositoryIT.java index d2eca8b9..b42772e3 100644 --- a/application-service/src/test/java/com/devhire/application/repository/ApplicationRepositoryIT.java +++ b/application-service/src/test/java/com/devhire/application/repository/ApplicationRepositoryIT.java @@ -5,8 +5,8 @@ import com.devhire.application.entity.JobApplication; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; +import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.domain.PageRequest; import org.springframework.jdbc.core.JdbcTemplate; @@ -14,7 +14,7 @@ import org.springframework.test.context.DynamicPropertySource; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.postgresql.PostgreSQLContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -28,7 +28,7 @@ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class ApplicationRepositoryIT { @Container - static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>("postgres:17-alpine"); + static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer("postgres:17-alpine"); @DynamicPropertySource static void datasource(DynamicPropertyRegistry registry) { diff --git a/audit-service/Dockerfile b/audit-service/Dockerfile index d729c982..3ed11681 100644 --- a/audit-service/Dockerfile +++ b/audit-service/Dockerfile @@ -1,4 +1,4 @@ -FROM maven:3.9.12-eclipse-temurin-21 AS build +FROM maven:3.9.14-eclipse-temurin-25 AS build WORKDIR /workspace ARG SERVICE_NAME=audit-service COPY pom.xml . @@ -17,7 +17,7 @@ COPY common-lib/src common-lib/src COPY ${SERVICE_NAME}/src ${SERVICE_NAME}/src RUN mvn -B -T1 -pl ${SERVICE_NAME} -am package -DskipTests -FROM eclipse-temurin:21-jre-alpine +FROM eclipse-temurin:25-jre-alpine ARG SERVICE_NAME=audit-service ARG BUILD_VERSION=0.4.0-SNAPSHOT ARG VCS_REF=local diff --git a/audit-service/pom.xml b/audit-service/pom.xml index d4ae8494..4cb94e2e 100644 --- a/audit-service/pom.xml +++ b/audit-service/pom.xml @@ -16,8 +16,8 @@ org.springframework.bootspring-boot-starter-validation org.springframework.bootspring-boot-starter-data-jpa org.springframework.bootspring-boot-starter-actuator - org.springframework.kafkaspring-kafka - org.flywaydbflyway-core + org.springframework.bootspring-boot-starter-kafka + org.springframework.bootspring-boot-starter-flyway org.flywaydbflyway-database-postgresql org.postgresqlpostgresqlruntime org.springdocspringdoc-openapi-starter-webmvc-ui${springdoc.version} @@ -25,8 +25,10 @@ io.micrometermicrometer-tracing-bridge-otel io.opentelemetryopentelemetry-exporter-otlp org.springframework.bootspring-boot-starter-testtest - org.testcontainerspostgresqltest - org.testcontainersjunit-jupitertest + org.springframework.bootspring-boot-starter-data-jpa-testtest + org.springframework.bootspring-boot-starter-flyway-testtest + org.testcontainerstestcontainers-postgresqltest + org.testcontainerstestcontainers-junit-jupitertest org.springframework.bootspring-boot-maven-plugin diff --git a/audit-service/src/main/java/com/devhire/audit/repository/AuditLogSpecifications.java b/audit-service/src/main/java/com/devhire/audit/repository/AuditLogSpecifications.java index 8d453fd0..d6fb8ea5 100644 --- a/audit-service/src/main/java/com/devhire/audit/repository/AuditLogSpecifications.java +++ b/audit-service/src/main/java/com/devhire/audit/repository/AuditLogSpecifications.java @@ -12,13 +12,13 @@ private AuditLogSpecifications() { } public static Specification actorId(UUID actorId) { - return actorId == null ? null : (root, query, criteriaBuilder) -> + return actorId == null ? Specification.unrestricted() : (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("actorId"), actorId); } public static Specification action(String action) { if (action == null || action.isBlank()) { - return null; + return Specification.unrestricted(); } String normalized = action.toLowerCase(Locale.ROOT); return (root, query, criteriaBuilder) -> @@ -26,12 +26,12 @@ public static Specification action(String action) { } public static Specification occurredFrom(Instant from) { - return from == null ? null : (root, query, criteriaBuilder) -> + return from == null ? Specification.unrestricted() : (root, query, criteriaBuilder) -> criteriaBuilder.greaterThanOrEqualTo(root.get("occurredAt"), from); } public static Specification occurredTo(Instant to) { - return to == null ? null : (root, query, criteriaBuilder) -> + return to == null ? Specification.unrestricted() : (root, query, criteriaBuilder) -> criteriaBuilder.lessThanOrEqualTo(root.get("occurredAt"), to); } } diff --git a/audit-service/src/test/java/com/devhire/audit/repository/AuditLogRepositoryIT.java b/audit-service/src/test/java/com/devhire/audit/repository/AuditLogRepositoryIT.java index c25c1bea..e36583ef 100644 --- a/audit-service/src/test/java/com/devhire/audit/repository/AuditLogRepositoryIT.java +++ b/audit-service/src/test/java/com/devhire/audit/repository/AuditLogRepositoryIT.java @@ -3,12 +3,12 @@ import com.devhire.audit.entity.AuditLog; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; +import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase; import org.springframework.data.jpa.domain.Specification; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.postgresql.PostgreSQLContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -22,7 +22,7 @@ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class AuditLogRepositoryIT { @Container - static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>("postgres:17-alpine"); + static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer("postgres:17-alpine"); @DynamicPropertySource static void datasource(DynamicPropertyRegistry registry) { diff --git a/auth-service/Dockerfile b/auth-service/Dockerfile index 54b23d1a..1e741e6f 100644 --- a/auth-service/Dockerfile +++ b/auth-service/Dockerfile @@ -1,4 +1,4 @@ -FROM maven:3.9.12-eclipse-temurin-21 AS build +FROM maven:3.9.14-eclipse-temurin-25 AS build WORKDIR /workspace ARG SERVICE_NAME=auth-service COPY pom.xml . @@ -17,7 +17,7 @@ COPY common-lib/src common-lib/src COPY ${SERVICE_NAME}/src ${SERVICE_NAME}/src RUN mvn -B -T1 -pl ${SERVICE_NAME} -am package -DskipTests -FROM eclipse-temurin:21-jre-alpine +FROM eclipse-temurin:25-jre-alpine ARG SERVICE_NAME=auth-service ARG BUILD_VERSION=0.4.0-SNAPSHOT ARG VCS_REF=local diff --git a/auth-service/pom.xml b/auth-service/pom.xml index 1477a7f1..61ff45bf 100644 --- a/auth-service/pom.xml +++ b/auth-service/pom.xml @@ -36,12 +36,12 @@ spring-boot-starter-data-redis - org.springframework.kafka - spring-kafka + org.springframework.boot + spring-boot-starter-kafka - org.flywaydb - flyway-core + org.springframework.boot + spring-boot-starter-flyway org.flywaydb @@ -95,6 +95,16 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-data-jpa-test + test + + + org.springframework.boot + spring-boot-starter-flyway-test + test + org.springframework.security spring-security-test @@ -102,12 +112,12 @@ org.testcontainers - postgresql + testcontainers-postgresql test org.testcontainers - junit-jupiter + testcontainers-junit-jupiter test diff --git a/auth-service/src/test/java/com/devhire/auth/repository/AuthRepositoryIT.java b/auth-service/src/test/java/com/devhire/auth/repository/AuthRepositoryIT.java index 2f78b9d1..3d3747a0 100644 --- a/auth-service/src/test/java/com/devhire/auth/repository/AuthRepositoryIT.java +++ b/auth-service/src/test/java/com/devhire/auth/repository/AuthRepositoryIT.java @@ -5,14 +5,14 @@ import com.devhire.common.security.UserRole; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; +import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; -import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.postgresql.PostgreSQLContainer; import java.time.Instant; import java.util.UUID; @@ -25,7 +25,7 @@ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class AuthRepositoryIT { @Container - static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>("postgres:17-alpine"); + static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer("postgres:17-alpine"); @DynamicPropertySource static void datasource(DynamicPropertyRegistry registry) { diff --git a/common-lib/pom.xml b/common-lib/pom.xml index 401cebfd..042923a8 100644 --- a/common-lib/pom.xml +++ b/common-lib/pom.xml @@ -51,10 +51,13 @@ com.fasterxml.jackson.core jackson-databind + + org.springframework.boot + spring-boot-jackson2 + com.fasterxml.jackson.datatype jackson-datatype-jsr310 - test org.springframework.boot diff --git a/company-service/Dockerfile b/company-service/Dockerfile index 8f78e2af..7ccbf57c 100644 --- a/company-service/Dockerfile +++ b/company-service/Dockerfile @@ -1,4 +1,4 @@ -FROM maven:3.9.12-eclipse-temurin-21 AS build +FROM maven:3.9.14-eclipse-temurin-25 AS build WORKDIR /workspace ARG SERVICE_NAME=company-service COPY pom.xml . @@ -17,7 +17,7 @@ COPY common-lib/src common-lib/src COPY ${SERVICE_NAME}/src ${SERVICE_NAME}/src RUN mvn -B -T1 -pl ${SERVICE_NAME} -am package -DskipTests -FROM eclipse-temurin:21-jre-alpine +FROM eclipse-temurin:25-jre-alpine ARG SERVICE_NAME=company-service ARG BUILD_VERSION=0.4.0-SNAPSHOT ARG VCS_REF=local diff --git a/company-service/pom.xml b/company-service/pom.xml index 20385742..c819cc1b 100644 --- a/company-service/pom.xml +++ b/company-service/pom.xml @@ -16,8 +16,8 @@ org.springframework.bootspring-boot-starter-validation org.springframework.bootspring-boot-starter-data-jpa org.springframework.bootspring-boot-starter-actuator - org.springframework.kafkaspring-kafka - org.flywaydbflyway-core + org.springframework.bootspring-boot-starter-kafka + org.springframework.bootspring-boot-starter-flyway org.flywaydbflyway-database-postgresql org.postgresqlpostgresqlruntime org.springdocspringdoc-openapi-starter-webmvc-ui${springdoc.version} @@ -25,8 +25,10 @@ io.micrometermicrometer-tracing-bridge-otel io.opentelemetryopentelemetry-exporter-otlp org.springframework.bootspring-boot-starter-testtest - org.testcontainerspostgresqltest - org.testcontainersjunit-jupitertest + org.springframework.bootspring-boot-starter-data-jpa-testtest + org.springframework.bootspring-boot-starter-flyway-testtest + org.testcontainerstestcontainers-postgresqltest + org.testcontainerstestcontainers-junit-jupitertest org.springframework.bootspring-boot-maven-plugin diff --git a/company-service/src/test/java/com/devhire/company/repository/CompanyRepositoryIT.java b/company-service/src/test/java/com/devhire/company/repository/CompanyRepositoryIT.java index ca38bf3c..644019de 100644 --- a/company-service/src/test/java/com/devhire/company/repository/CompanyRepositoryIT.java +++ b/company-service/src/test/java/com/devhire/company/repository/CompanyRepositoryIT.java @@ -4,13 +4,13 @@ import com.devhire.company.entity.CompanyStatus; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; +import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.domain.PageRequest; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.postgresql.PostgreSQLContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -24,7 +24,7 @@ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class CompanyRepositoryIT { @Container - static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>("postgres:17-alpine"); + static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer("postgres:17-alpine"); @DynamicPropertySource static void datasource(DynamicPropertyRegistry registry) { diff --git a/deploy/terraform/aws/environments/dev/versions.tf b/deploy/terraform/aws/environments/dev/versions.tf index c64e13ef..8c119a6c 100644 --- a/deploy/terraform/aws/environments/dev/versions.tf +++ b/deploy/terraform/aws/environments/dev/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 5.84" + version = "~> 6.45" } } } diff --git a/deploy/terraform/aws/environments/prod/versions.tf b/deploy/terraform/aws/environments/prod/versions.tf index c64e13ef..8c119a6c 100644 --- a/deploy/terraform/aws/environments/prod/versions.tf +++ b/deploy/terraform/aws/environments/prod/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 5.84" + version = "~> 6.45" } } } diff --git a/deploy/terraform/aws/environments/staging/versions.tf b/deploy/terraform/aws/environments/staging/versions.tf index c64e13ef..8c119a6c 100644 --- a/deploy/terraform/aws/environments/staging/versions.tf +++ b/deploy/terraform/aws/environments/staging/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 5.84" + version = "~> 6.45" } } } diff --git a/deploy/terraform/aws/modules/container/versions.tf b/deploy/terraform/aws/modules/container/versions.tf index eba66bdc..5c6a897f 100644 --- a/deploy/terraform/aws/modules/container/versions.tf +++ b/deploy/terraform/aws/modules/container/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 5.84" + version = "~> 6.45" } } } diff --git a/deploy/terraform/aws/modules/data/versions.tf b/deploy/terraform/aws/modules/data/versions.tf index eba66bdc..5c6a897f 100644 --- a/deploy/terraform/aws/modules/data/versions.tf +++ b/deploy/terraform/aws/modules/data/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 5.84" + version = "~> 6.45" } } } diff --git a/deploy/terraform/aws/modules/eks/versions.tf b/deploy/terraform/aws/modules/eks/versions.tf index eba66bdc..5c6a897f 100644 --- a/deploy/terraform/aws/modules/eks/versions.tf +++ b/deploy/terraform/aws/modules/eks/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 5.84" + version = "~> 6.45" } } } diff --git a/deploy/terraform/aws/modules/network/versions.tf b/deploy/terraform/aws/modules/network/versions.tf index eba66bdc..5c6a897f 100644 --- a/deploy/terraform/aws/modules/network/versions.tf +++ b/deploy/terraform/aws/modules/network/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 5.84" + version = "~> 6.45" } } } diff --git a/deploy/terraform/aws/modules/secrets/versions.tf b/deploy/terraform/aws/modules/secrets/versions.tf index eba66bdc..5c6a897f 100644 --- a/deploy/terraform/aws/modules/secrets/versions.tf +++ b/deploy/terraform/aws/modules/secrets/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "~> 5.84" + version = "~> 6.45" } } } diff --git a/docs/README_EN.md b/docs/README_EN.md index f1e36b60..d061efa0 100644 --- a/docs/README_EN.md +++ b/docs/README_EN.md @@ -1,6 +1,6 @@ # DevHire Cloud - Microservices Recruitment Platform -DevHire Cloud is a production-engineering portfolio for a recruitment platform: Java 21, Spring Boot 3.5, Next.js, Kafka, OpenSearch, PostgreSQL, Redis, Docker, Kubernetes, Terraform, and a controlled Claude Haiku AI assistant. The repository is written for senior review: it emphasizes service boundaries, owned data, event reliability, observability, security, CI/CD, cloud readiness, and evidence that can be checked without trusting the README. +DevHire Cloud is a production-engineering portfolio for a recruitment platform: Java 21, Spring Boot 4.0, Next.js, Kafka, OpenSearch, PostgreSQL, Redis, Docker, Kubernetes, Terraform, and a controlled Claude Haiku AI assistant. The repository is written for senior review: it emphasizes service boundaries, owned data, event reliability, observability, security, CI/CD, cloud readiness, and evidence that can be checked without trusting the README. ## 30-Second Reviewer Brief diff --git a/docs/README_JA.md b/docs/README_JA.md index 9db91fec..cf4bb7f4 100644 --- a/docs/README_JA.md +++ b/docs/README_JA.md @@ -1,6 +1,6 @@ # DevHire Cloud - Microservices Recruitment Platform -DevHire Cloud は、Java 21 / Spring Boot 3.5 で構築した採用プラットフォームの production engineering portfolio です。小規模な ITviec / LinkedIn Jobs のようなドメインを使い、明確な service boundary、service-owned database、Kafka/outbox、OpenSearch、observability、Docker/Kubernetes/Terraform、CI/CD、security evidence、Claude Haiku AI assistant を示します。 +DevHire Cloud は、Java 21 / Spring Boot 4.0 で構築した採用プラットフォームの production engineering portfolio です。小規模な ITviec / LinkedIn Jobs のようなドメインを使い、明確な service boundary、service-owned database、Kafka/outbox、OpenSearch、observability、Docker/Kubernetes/Terraform、CI/CD、security evidence、Claude Haiku AI assistant を示します。 ## Public Repository Status diff --git a/docs/demo-script.md b/docs/demo-script.md index 0c2d6ab2..3181475c 100644 --- a/docs/demo-script.md +++ b/docs/demo-script.md @@ -100,7 +100,7 @@ Show these files: Final message for recruiter: -DevHire Cloud demonstrates Java 21, Spring Boot 3.5, Spring Cloud Gateway, JWT security, service-owned databases, Flyway, Kafka/outbox, OpenSearch, Claude Haiku RAG assistant, Gmail SMTP hardening, observability, CI/CD, Docker, Kubernetes/Helm/GitOps, tests, and real frontend E2E smoke coverage. +DevHire Cloud demonstrates Java 21, Spring Boot 4.0, Spring Cloud Gateway, JWT security, service-owned databases, Flyway, Kafka/outbox, OpenSearch, Claude Haiku RAG assistant, Gmail SMTP hardening, observability, CI/CD, Docker, Kubernetes/Helm/GitOps, tests, and real frontend E2E smoke coverage. Cleanup after a recruiter demo: diff --git a/docs/dependency-maintenance.md b/docs/dependency-maintenance.md index f79c104d..91a6f1ae 100644 --- a/docs/dependency-maintenance.md +++ b/docs/dependency-maintenance.md @@ -10,11 +10,18 @@ DevHire Cloud keeps Dependabot enabled because dependency hygiene is part of the | Docker base images patch/minor | Batch by runtime family | Keeps image drift small without forcing many tiny releases. | | Maven patch/minor | Accept when tests and smoke gates pass | Backend dependency changes can affect contracts and runtime behavior. | | npm patch/minor | Accept with typecheck, build, and Playwright smoke | Frontend runtime changes are visible and should be screenshot-checked. | +| TypeScript major | Defer until the Next.js production build and compiler API are compatible | A standalone `tsc` pass is insufficient when the framework also loads the TypeScript compiler API. | | Terraform provider major | Defer until migration review | AWS provider major upgrades can change resources and state behavior. | | Node major | Defer until Docker/frontend compatibility review | Runtime major upgrades can affect Next.js build and image behavior. | | Spring platform major | Defer until compatibility matrix review | Spring Boot/Spring Cloud compatibility is a hard production constraint. | -## Current v0.6 Release-Readiness State +## 2026-07-15 Coordinated Integration Batch + +This maintenance window consolidates 23 remote branches into one reviewable change: 1 README correction and 22 Dependabot updates spanning GitHub Actions, Docker images, Maven, npm, and Terraform. Major platform changes were reviewed together because Spring Boot 4, Testcontainers 2, Node 26, and the AWS provider 6 line require compatibility fixes beyond a mechanical version bump. + +Local validation covered the full 12-module Maven reactor, 417 frontend tests, 22 property tests at 500 runs each, 52 Playwright scenarios across desktop and Pixel 7 projects, all three Terraform environments, documentation and repository audits, and an npm audit with zero known vulnerabilities. TypeScript remains on 6.0.3 because the current Next.js production build does not yet load the TypeScript 7 compiler API correctly; Dependabot ignores that major line until the framework boundary is compatible. Pull-request CI remains the final gate for the complete Docker matrix, CodeQL, secret scanning, SBOM generation, and filesystem scanning. + +## 2026-05 Release-Readiness Baseline The 2026-05-14 live GitHub scan originally found 20 Dependabot pull requests: 9 Docker, 1 GitHub Actions, 2 Maven, 4 npm/frontend, 3 Terraform, and 1 other. `scripts/dependabot-zero-noise.ps1 -Apply` was then run from an owner-authenticated shell. It found 0 clean merge candidates, commented on each PR, closed/deferred all 20 stale/behind/risky updates, and the remote Dependabot branches were pruned. No dependency PR was force-merged into the release. diff --git a/docs/production-checklist.md b/docs/production-checklist.md index 7a2fef0d..d8dfa8a7 100644 --- a/docs/production-checklist.md +++ b/docs/production-checklist.md @@ -1,6 +1,6 @@ # Production Portfolio Checklist -- Java 21 and Spring Boot 3.5.x multi-module build. +- Java 21 and Spring Boot 4.0.x multi-module build. - Spring Cloud Gateway with JWT validation, CORS, route security, and Redis rate limit. - Role-based authorization for Admin, Employer, and Candidate. - BCrypt password hashing. diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 17b25c8c..64f0439a 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,9 +1,9 @@ -FROM node:24-alpine AS deps +FROM node:26-alpine AS deps WORKDIR /app COPY frontend/package*.json ./ RUN npm ci -FROM node:24-alpine AS builder +FROM node:26-alpine AS builder WORKDIR /app ARG NEXT_PUBLIC_API_BASE_URL=http://localhost:8080 ENV NEXT_TELEMETRY_DISABLED=1 @@ -12,7 +12,7 @@ COPY --from=deps /app/node_modules ./node_modules COPY frontend ./ RUN npm run build -FROM node:24-alpine AS runner +FROM node:26-alpine AS runner WORKDIR /app ARG SERVICE_NAME=frontend ARG BUILD_VERSION=0.4.0 diff --git a/frontend/e2e/code-assessment-flow.spec.ts b/frontend/e2e/code-assessment-flow.spec.ts index 89591e67..e64d1493 100644 --- a/frontend/e2e/code-assessment-flow.spec.ts +++ b/frontend/e2e/code-assessment-flow.spec.ts @@ -660,6 +660,10 @@ async function routeAdminApi(page: Page) { } test.describe("LeetCode-style code assessment E2E", () => { + test.beforeEach(async ({ page }) => { + await page.clock.setFixedTime(new Date(NOW)); + }); + test("candidate runs custom visible input, submits Java, and never sees hidden payloads", async ({ page }) => { await routeCandidateCodeAssessmentApi(page); await login(page, "candidate"); diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 2e77e36a..1ff3216c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,62 +11,100 @@ "@monaco-editor/react": "^4.7.0", "@stomp/stompjs": "^7.3.0", "lucide-react": "1.14.0", - "next": "16.2.6", - "react": "19.2.5", - "react-dom": "19.2.5", + "next": "16.2.10", + "react": "19.2.7", + "react-dom": "19.2.7", "sockjs-client": "^1.6.1" }, "devDependencies": { "@axe-core/playwright": "^4.10.0", "@next/bundle-analyzer": "^16.2.6", - "@playwright/test": "1.57.0", + "@playwright/test": "1.60.0", "@testing-library/dom": "^10.4.0", "@testing-library/react": "^16.3.0", "@types/jsdom": "^28.0.3", "@types/node": "24.10.2", - "@types/react": "19.2.14", + "@types/react": "19.2.17", "@types/react-dom": "19.2.3", "@types/sockjs-client": "^1.5.4", - "fast-check": "^3.23.0", - "jsdom": "^25.0.1", + "fast-check": "^4.8.0", + "jsdom": "^29.1.1", + "playwright-core": "1.60.0", "typescript": "6.0.3" } }, "node_modules/@asamuzakjp/css-color": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", - "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz", + "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-calc": "^2.1.3", - "@csstools/css-color-parser": "^3.0.9", - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3", - "lru-cache": "^10.4.3" + "@asamuzakjp/generational-cache": "^1.0.1", + "@csstools/css-calc": "^3.2.0", + "@csstools/css-color-parser": "^4.1.0", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-7.1.1.tgz", + "integrity": "sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/generational-cache": "^1.0.1", + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.2.1", + "is-potential-custom-element-name": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, + "node_modules/@asamuzakjp/generational-cache": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz", + "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@axe-core/playwright": { - "version": "4.11.3", - "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.11.3.tgz", - "integrity": "sha512-h/kfksv4F0cVIDlKpT4700OehdRgpvuVskuQ2nb7/JmtWUXpe9ftHAPtwyXGvVSsa6SJ64A9ER7Zrzc/sIvC4w==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.12.1.tgz", + "integrity": "sha512-rMd7xriptqKpP+w5265i4Hdkv2X5kbu6uiBi/B2I7uf3hieRBM3qDCfaKPtxfiYb2mKXfF+yLODJwIx+Jv1GDw==", "dev": true, "license": "MPL-2.0", "dependencies": { - "axe-core": "~4.11.4" + "axe-core": "~4.12.1" }, "peerDependencies": { "playwright-core": ">= 1.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -75,9 +113,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true, "license": "MIT", "engines": { @@ -85,19 +123,32 @@ } }, "node_modules/@babel/runtime": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", - "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.0.tgz", + "integrity": "sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==", "dev": true, "funding": [ { @@ -111,13 +162,13 @@ ], "license": "MIT-0", "engines": { - "node": ">=18" + "node": ">=20.19.0" } }, "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz", + "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==", "dev": true, "funding": [ { @@ -131,17 +182,17 @@ ], "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.9.tgz", + "integrity": "sha512-paQcIaOO53Rk5+YrBaBjm/SgrV4INImjo2BT1DtQRYr+XeTRbeAYlS+jxXp9drqvKmtFnWRJKIalDLhZZDu42A==", "dev": true, "funding": [ { @@ -155,21 +206,21 @@ ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" + "@csstools/color-helpers": "^6.1.0", + "@csstools/css-calc": "^3.2.1" }, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", "dev": true, "funding": [ { @@ -184,16 +235,41 @@ "license": "MIT", "peer": true, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.6.tgz", + "integrity": "sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } } }, "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", "dev": true, "funding": [ { @@ -208,7 +284,7 @@ "license": "MIT", "peer": true, "engines": { - "node": ">=18" + "node": ">=20.19.0" } }, "node_modules/@discoveryjs/json-ext": { @@ -222,15 +298,33 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", + "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, + "node_modules/@exodus/bytes": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz", + "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, "node_modules/@img/colour": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", @@ -721,9 +815,9 @@ } }, "node_modules/@next/bundle-analyzer": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-16.2.6.tgz", - "integrity": "sha512-amPkVtHCTJAdBwyhhl5+qztHk24O4JlASgrWqh15AmnYi74apfZR46NGC0u4pM6BMAU1mYld4WdzD3cRBP3dOA==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-16.2.10.tgz", + "integrity": "sha512-KcepWhb3IVniZgm00GSSCQDEUQqZXuXtuXRh8J6e3Un342TcQ77iK4DedeEkct+fcx7yFEDL2J6z4Jeho5JDAw==", "dev": true, "license": "MIT", "dependencies": { @@ -731,15 +825,15 @@ } }, "node_modules/@next/env": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.6.tgz", - "integrity": "sha512-gd8HoHN4ufj73WmR3JmVolrpJR47ILK6LouP5xElPglaVxir6e1a7VzvTvDWkOoPXT9rkkTzyCxBu4yeZfZwcw==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.10.tgz", + "integrity": "sha512-zLPxg9M0MEHmygpj5OuxjQ+vHMiy/K7cSp74G8ecYolmgUWw0RwN02tF56npup/+qaI8JB97hQgS/r2Hb6QwVA==", "license": "MIT" }, "node_modules/@next/swc-darwin-arm64": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.6.tgz", - "integrity": "sha512-ZJGkkcNfYgrrMkqOdZ7zoLa1TOy0qpcMfk/z4Mh/FKUz40gVO+HNQWqmLxf67Z5WB64DRp0dhEbyHfel+6sJUg==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.10.tgz", + "integrity": "sha512-v9IdJCa0H0mbo+8z5zwUpOk1Vj7RjkcI5uNYf5Ws1y6szf/p3Mzl9hLaST8SCt6L9h8NGnruZcd2+o0NTNwDhA==", "cpu": [ "arm64" ], @@ -753,9 +847,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.6.tgz", - "integrity": "sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.10.tgz", + "integrity": "sha512-17IS0jJRViROGmA9uGdNR8VPJpfbnaVG7E9qhso5jDLkmyd0lSDORWxbcKINzcFqzZqGwGtMSnrFRxBpuUYjLQ==", "cpu": [ "x64" ], @@ -769,9 +863,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.6.tgz", - "integrity": "sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.10.tgz", + "integrity": "sha512-GRQRsRtuciNJvB54AvvuQTiq0oZtFwa1owQqtZD8wwnGpM2L39MV22kpI72YSXLKIyY40LC66EiLFv4PiicXxg==", "cpu": [ "arm64" ], @@ -785,9 +879,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.6.tgz", - "integrity": "sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.10.tgz", + "integrity": "sha512-zkN9MQYS7UQBro+FnISUq1itaQjXI9xqISzuQ+2bc921NcJ1x4yPCqrn77tVN6/dOOXaaWVX3k6/bR07pPwK+A==", "cpu": [ "arm64" ], @@ -801,9 +895,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.6.tgz", - "integrity": "sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.10.tgz", + "integrity": "sha512-iCVJnwvrPYECvA6WM/7+oo+OiTvedIKLxtCLAZP4xZR3nXa1zmzZyLPbYCmWvpd4CvMYF1EMTafd0ii3DygLvA==", "cpu": [ "x64" ], @@ -817,9 +911,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.6.tgz", - "integrity": "sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.10.tgz", + "integrity": "sha512-ov2g4H0dHY9bPoOU83m91hWT7Iq5qy13bUnyyshLU3HGR1Ownn0X9QpmDPc5iIUaahTp7f7LeGAhV4DSFtackw==", "cpu": [ "x64" ], @@ -833,9 +927,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.6.tgz", - "integrity": "sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.10.tgz", + "integrity": "sha512-DwAnhLX76HQiFFQNgWlcK+JzlnD1rZ+UK/WY0ZMI/deXpvgnesjNYrqcfo1JzBuz4Kf7o3brIBL0glI1junatA==", "cpu": [ "arm64" ], @@ -849,9 +943,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.6.tgz", - "integrity": "sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.10.tgz", + "integrity": "sha512-0JXq3b85Jk9Jg4ntLUbXSPvoDw3gpZou7twuKdoFG2jOw635v7+IiXfTaa0TxVMyx78pUjnrVYwLgjKfX4e6/A==", "cpu": [ "x64" ], @@ -865,14 +959,14 @@ } }, "node_modules/@playwright/test": { - "version": "1.57.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.57.0.tgz", - "integrity": "sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==", + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.60.0.tgz", + "integrity": "sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==", "devOptional": true, "license": "Apache-2.0", "peer": true, "dependencies": { - "playwright": "1.57.0" + "playwright": "1.60.0" }, "bin": { "playwright": "cli.js" @@ -972,39 +1066,6 @@ "undici-types": "^7.21.0" } }, - "node_modules/@types/jsdom/node_modules/entities": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", - "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=20.19.0" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/@types/jsdom/node_modules/parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", - "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", - "dev": true, - "license": "MIT", - "dependencies": { - "entities": "^8.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/@types/jsdom/node_modules/undici-types": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.25.0.tgz", - "integrity": "sha512-AXNgS1Byr27fTI+2bsPEkV9CxkT8H6xNyRI68b3TatlZo3RkzlqQBLL+w7SmGPVpokjHbcuNVQUWE7FRTg+LRA==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/node": { "version": "24.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.2.tgz", @@ -1015,10 +1076,17 @@ "undici-types": "~7.16.0" } }, + "node_modules/@types/node/node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", "dev": true, "license": "MIT", "peer": true, @@ -1059,9 +1127,9 @@ "optional": true }, "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "dev": true, "license": "MIT", "bin": { @@ -1084,16 +1152,6 @@ "node": ">=0.4.0" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1127,17 +1185,10 @@ "dequal": "^2.0.3" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, "node_modules/axe-core": { - "version": "4.11.4", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.4.tgz", - "integrity": "sha512-KunSNx+TVpkAw/6ULfhnx+HWRecjqZGTOyquAoWHYLRSdK1tB5Ihce1ZW+UY3fj33bYAFWPu7W/GRSmmrCGuxA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.12.1.tgz", + "integrity": "sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==", "dev": true, "license": "MPL-2.0", "engines": { @@ -1145,9 +1196,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.25", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.25.tgz", - "integrity": "sha512-QO/VHsXCQdnzADMfmkeOPvHdIAkoB7i0/rGjINPJEetLx75hNttVWGQ/jycHUDP9zZ9rupbm60WRxcwViB0MiA==", + "version": "2.10.43", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz", + "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" @@ -1156,24 +1207,20 @@ "node": ">=6.0.0" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" + "require-from-string": "^2.0.2" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001791", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz", - "integrity": "sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==", + "version": "1.0.30001805", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001805.tgz", + "integrity": "sha512-52noaS3DubycKSXaU30TwPGIp+POyQSUVa5jBEq3vkRkY0kjyb3LQgvhU6WGyCcyXqVLWO0Cw0Q6BSdD0kUfVA==", "funding": [ { "type": "opencollective", @@ -1196,19 +1243,6 @@ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", @@ -1219,27 +1253,20 @@ "node": ">= 10" } }, - "node_modules/cssstyle": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", - "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^3.2.0", - "rrweb-cssom": "^0.8.0" + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" }, "engines": { - "node": ">=18" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "node_modules/cssstyle/node_modules/rrweb-cssom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", - "dev": true, - "license": "MIT" - }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -1248,17 +1275,17 @@ "license": "MIT" }, "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", "dev": true, "license": "MIT", "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, "node_modules/debounce": { @@ -1269,21 +1296,12 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "ms": "^2.1.1" } }, "node_modules/decimal.js": { @@ -1293,16 +1311,6 @@ "dev": true, "license": "MIT" }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -1331,29 +1339,14 @@ "license": "MIT" }, "node_modules/dompurify": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.2.tgz", - "integrity": "sha512-lHeS9SA/IKeIFFyYciHBr2n0v1VMPlSj843HdLOwjb2OxNwdq9Xykxqhk+FE42MzAdHvInbAolSE4mhahPpjXA==", + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.12.tgz", + "integrity": "sha512-zQvGet8Z2sWbQhCmfFz/T5QWH2oBmjnqK3qvOjaqaNLrLEF912WamU+ohnTp0TCep/MFVHpdJuCZEdFOdTnEFg==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -1362,67 +1355,18 @@ "license": "MIT" }, "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", "dev": true, "license": "BSD-2-Clause", "engines": { - "node": ">=0.12" + "node": ">=20.19.0" }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1446,9 +1390,9 @@ } }, "node_modules/fast-check": { - "version": "3.23.2", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz", - "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.9.0.tgz", + "integrity": "sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg==", "dev": true, "funding": [ { @@ -1462,10 +1406,10 @@ ], "license": "MIT", "dependencies": { - "pure-rand": "^6.1.0" + "pure-rand": "^8.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=12.17.0" } }, "node_modules/faye-websocket": { @@ -1480,23 +1424,6 @@ "node": ">=0.8.0" } }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -1512,68 +1439,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", @@ -1590,59 +1455,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", - "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", "dev": true, "license": "MIT", "dependencies": { - "whatwg-encoding": "^3.1.1" + "@exodus/bytes": "^1.6.0" }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, "node_modules/html-escaper": { @@ -1658,47 +1481,6 @@ "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", "license": "MIT" }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -1730,39 +1512,39 @@ "license": "MIT" }, "node_modules/jsdom": { - "version": "25.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", - "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-29.1.1.tgz", + "integrity": "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==", "dev": true, "license": "MIT", "dependencies": { - "cssstyle": "^4.1.0", - "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.5", + "@asamuzakjp/css-color": "^5.1.11", + "@asamuzakjp/dom-selector": "^7.1.1", + "@bramus/specificity": "^2.4.2", + "@csstools/css-syntax-patches-for-csstree": "^1.1.3", + "@exodus/bytes": "^1.15.0", + "css-tree": "^3.2.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.12", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.1", + "lru-cache": "^11.3.5", + "parse5": "^8.0.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^5.0.0", + "tough-cookie": "^6.0.1", + "undici": "^7.25.0", "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", - "ws": "^8.18.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.1", "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.13.0 || >=24.0.0" }, "peerDependencies": { - "canvas": "^2.11.2" + "canvas": "^3.0.0" }, "peerDependenciesMeta": { "canvas": { @@ -1771,11 +1553,14 @@ } }, "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", "dev": true, - "license": "ISC" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } }, "node_modules/lucide-react": { "version": "1.14.0", @@ -1808,38 +1593,12 @@ "node": ">= 18" } }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } + "license": "CC0-1.0" }, "node_modules/monaco-editor": { "version": "0.55.1", @@ -1869,9 +1628,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", @@ -1887,12 +1646,12 @@ } }, "node_modules/next": { - "version": "16.2.6", - "resolved": "https://registry.npmjs.org/next/-/next-16.2.6.tgz", - "integrity": "sha512-qOVgKJg1+At15NpeUP+eJgCHvTCgXsogweq87Ri/Ix7PkqQHg4sdaXmSFqKlgaIXE4kW0g25LE68W87UANlHtw==", + "version": "16.2.10", + "resolved": "https://registry.npmjs.org/next/-/next-16.2.10.tgz", + "integrity": "sha512-2som5AVXb3kE6Yjine3/mNbBayYF58eguBWIVVUdr1y/L426xyVEgYxgBG+1QC34P2x5E+tcDup6XkuOAX3dCA==", "license": "MIT", "dependencies": { - "@next/env": "16.2.6", + "@next/env": "16.2.10", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", @@ -1906,14 +1665,14 @@ "node": ">=20.9.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "16.2.6", - "@next/swc-darwin-x64": "16.2.6", - "@next/swc-linux-arm64-gnu": "16.2.6", - "@next/swc-linux-arm64-musl": "16.2.6", - "@next/swc-linux-x64-gnu": "16.2.6", - "@next/swc-linux-x64-musl": "16.2.6", - "@next/swc-win32-arm64-msvc": "16.2.6", - "@next/swc-win32-x64-msvc": "16.2.6", + "@next/swc-darwin-arm64": "16.2.10", + "@next/swc-darwin-x64": "16.2.10", + "@next/swc-linux-arm64-gnu": "16.2.10", + "@next/swc-linux-arm64-musl": "16.2.10", + "@next/swc-linux-x64-gnu": "16.2.10", + "@next/swc-linux-x64-musl": "16.2.10", + "@next/swc-win32-arm64-msvc": "16.2.10", + "@next/swc-win32-x64-msvc": "16.2.10", "sharp": "^0.34.5" }, "peerDependencies": { @@ -1939,13 +1698,6 @@ } } }, - "node_modules/nwsapi": { - "version": "2.2.23", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", - "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", - "dev": true, - "license": "MIT" - }, "node_modules/opener": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", @@ -1957,13 +1709,13 @@ } }, "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", "dev": true, "license": "MIT", "dependencies": { - "entities": "^6.0.0" + "entities": "^8.0.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -1976,13 +1728,13 @@ "license": "ISC" }, "node_modules/playwright": { - "version": "1.57.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.57.0.tgz", - "integrity": "sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==", + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz", + "integrity": "sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.57.0" + "playwright-core": "1.60.0" }, "bin": { "playwright": "cli.js" @@ -1995,9 +1747,9 @@ } }, "node_modules/playwright-core": { - "version": "1.57.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.57.0.tgz", - "integrity": "sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==", + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz", + "integrity": "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==", "devOptional": true, "license": "Apache-2.0", "peer": true, @@ -2062,9 +1814,9 @@ } }, "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.2.tgz", + "integrity": "sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng==", "dev": true, "funding": [ { @@ -2085,9 +1837,9 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.2.5", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", - "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", "peer": true, "engines": { @@ -2095,16 +1847,16 @@ } }, "node_modules/react-dom": { - "version": "19.2.5", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", - "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "license": "MIT", "peer": true, "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.5" + "react": "^19.2.7" } }, "node_modules/react-is": { @@ -2114,19 +1866,22 @@ "dev": true, "license": "MIT" }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "license": "MIT" }, - "node_modules/rrweb-cssom": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", - "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", - "dev": true, - "license": "MIT" - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2147,13 +1902,6 @@ ], "license": "MIT" }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -2174,9 +1922,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "optional": true, "bin": { @@ -2265,15 +2013,6 @@ "url": "https://tidelift.com/funding/github/npm/sockjs-client" } }, - "node_modules/sockjs-client/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -2320,22 +2059,22 @@ "license": "MIT" }, "node_modules/tldts": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.8.tgz", + "integrity": "sha512-htwgN/8KRB3z3vnC0BOETVh2m499g5GmyTK9Wq5JBLX3FNz6tSBveAd+fQhzy9hkjif8vy2jwDMR1sGhLtZl2A==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^6.1.86" + "tldts-core": "^7.4.8" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "version": "7.4.8", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.8.tgz", + "integrity": "sha512-c1P7u0EhACHj7lPy4MJm8iTFEU8+nB0LCtddH0fhP7noaVoXAqafMtOOeX+ulpuPBqnrRgRhw494RICT3mbhnw==", "dev": true, "license": "MIT" }, @@ -2350,29 +2089,29 @@ } }, "node_modules/tough-cookie": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "tldts": "^6.1.32" + "tldts": "^7.0.5" }, "engines": { "node": ">=16" } }, "node_modules/tr46": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", "dev": true, "license": "MIT", "dependencies": { "punycode": "^2.3.1" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/tslib": { @@ -2395,10 +2134,20 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", + "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.28.0.tgz", + "integrity": "sha512-LJAfY+2w6HGeT8d8J1wNQsUGUEGio6NWWpwdwurQe4f6oojzCFuGLizl1KSve4irsTxyLly1QhEeE6iapdaIvQ==", "dev": true, "license": "MIT" }, @@ -2426,13 +2175,13 @@ } }, "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", "dev": true, "license": "BSD-2-Clause", "engines": { - "node": ">=12" + "node": ">=20" } }, "node_modules/webpack-bundle-analyzer": { @@ -2463,32 +2212,10 @@ "node": ">= 10.13.0" } }, - "node_modules/webpack-bundle-analyzer/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.5.tgz", + "integrity": "sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==", "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", @@ -2508,56 +2235,43 @@ "node": ">=0.8.0" } }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/whatwg-url": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", - "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", "dev": true, "license": "MIT", "dependencies": { - "tr46": "^5.1.0", - "webidl-conversions": "^7.0.0" + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" }, "engines": { - "node": ">=18" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, "node_modules/ws": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", - "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "version": "7.5.12", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.12.tgz", + "integrity": "sha512-1xGnbYN3zbog9CwuNDQULNRrTCLIn46/WmpR1f0w6PsCYQHkylZr5vkd6kfMZYV6pRnQkcPNRyiA8LsrNKyhpg==", "dev": true, "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=8.3.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "utf-8-validate": "^5.0.2" }, "peerDependenciesMeta": { "bufferutil": { diff --git a/frontend/package.json b/frontend/package.json index ad5654d8..8d34e47a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -30,28 +30,29 @@ "@monaco-editor/react": "^4.7.0", "@stomp/stompjs": "^7.3.0", "lucide-react": "1.14.0", - "next": "16.2.6", - "react": "19.2.5", - "react-dom": "19.2.5", + "next": "16.2.10", + "react": "19.2.7", + "react-dom": "19.2.7", "sockjs-client": "^1.6.1" }, "devDependencies": { "@axe-core/playwright": "^4.10.0", "@next/bundle-analyzer": "^16.2.6", - "@playwright/test": "1.57.0", + "@playwright/test": "1.60.0", "@testing-library/dom": "^10.4.0", "@testing-library/react": "^16.3.0", "@types/jsdom": "^28.0.3", "@types/node": "24.10.2", - "@types/react": "19.2.14", + "@types/react": "19.2.17", "@types/react-dom": "19.2.3", "@types/sockjs-client": "^1.5.4", - "fast-check": "^3.23.0", - "jsdom": "^25.0.1", + "fast-check": "^4.8.0", + "jsdom": "^29.1.1", + "playwright-core": "1.60.0", "typescript": "6.0.3" }, "overrides": { - "dompurify": "3.4.2", + "dompurify": "3.4.12", "postcss": "8.5.10" } } diff --git a/frontend/src/__tests__/hooks/useFocusTrap.test.ts b/frontend/src/__tests__/hooks/useFocusTrap.test.ts index 58025b00..110f9ab5 100644 --- a/frontend/src/__tests__/hooks/useFocusTrap.test.ts +++ b/frontend/src/__tests__/hooks/useFocusTrap.test.ts @@ -44,10 +44,10 @@ describe('useFocusTrap - DOM behavior', () => { // Should find: btn1, input1, link1, div1 (4 elements) // Should NOT find: btn-disabled, div-neg assert.equal(focusable.length, 4); - assert.equal((focusable[0] as HTMLElement).id, 'btn1'); - assert.equal((focusable[1] as HTMLElement).id, 'input1'); - assert.equal((focusable[2] as HTMLElement).id, 'link1'); - assert.equal((focusable[3] as HTMLElement).id, 'div1'); + assert.deepEqual( + new Set(focusable.map((element) => (element as HTMLElement).id)), + new Set(['btn1', 'input1', 'link1', 'div1']) + ); }); it('Tab on last element should cycle to first (simulated keydown logic)', () => { diff --git a/frontend/src/__tests__/properties/eventSerialization.property.test.ts b/frontend/src/__tests__/properties/eventSerialization.property.test.ts index f76e710d..e8cd3972 100644 --- a/frontend/src/__tests__/properties/eventSerialization.property.test.ts +++ b/frontend/src/__tests__/properties/eventSerialization.property.test.ts @@ -28,7 +28,11 @@ const arbNotificationEvent = fc.record({ type: arbNotificationType, title: fc.string({ minLength: 1, maxLength: 100 }), body: fc.string({ minLength: 1, maxLength: 500 }), - createdAt: fc.date({ min: new Date("2020-01-01"), max: new Date("2030-01-01") }) + createdAt: fc.date({ + min: new Date("2020-01-01"), + max: new Date("2030-01-01"), + noInvalidDate: true, + }) .map((d) => d.toISOString()), read: fc.boolean(), sequenceNumber: fc.nat(), diff --git a/job-service/Dockerfile b/job-service/Dockerfile index a6fdefd4..4c79a368 100644 --- a/job-service/Dockerfile +++ b/job-service/Dockerfile @@ -1,4 +1,4 @@ -FROM maven:3.9.12-eclipse-temurin-21 AS build +FROM maven:3.9.14-eclipse-temurin-25 AS build WORKDIR /workspace ARG SERVICE_NAME=job-service COPY pom.xml . @@ -17,7 +17,7 @@ COPY common-lib/src common-lib/src COPY ${SERVICE_NAME}/src ${SERVICE_NAME}/src RUN mvn -B -T1 -pl ${SERVICE_NAME} -am package -DskipTests -FROM eclipse-temurin:21-jre-alpine +FROM eclipse-temurin:25-jre-alpine ARG SERVICE_NAME=job-service ARG BUILD_VERSION=0.4.0-SNAPSHOT ARG VCS_REF=local diff --git a/job-service/pom.xml b/job-service/pom.xml index 5dd2aa45..491a5417 100644 --- a/job-service/pom.xml +++ b/job-service/pom.xml @@ -17,8 +17,8 @@ org.springframework.bootspring-boot-starter-data-jpa org.springframework.bootspring-boot-starter-actuator org.springframework.cloudspring-cloud-starter-openfeign - org.springframework.kafkaspring-kafka - org.flywaydbflyway-core + org.springframework.bootspring-boot-starter-kafka + org.springframework.bootspring-boot-starter-flyway org.flywaydbflyway-database-postgresql org.postgresqlpostgresqlruntime org.springdocspringdoc-openapi-starter-webmvc-ui${springdoc.version} @@ -26,8 +26,10 @@ io.micrometermicrometer-tracing-bridge-otel io.opentelemetryopentelemetry-exporter-otlp org.springframework.bootspring-boot-starter-testtest - org.testcontainerspostgresqltest - org.testcontainersjunit-jupitertest + org.springframework.bootspring-boot-starter-data-jpa-testtest + org.springframework.bootspring-boot-starter-flyway-testtest + org.testcontainerstestcontainers-postgresqltest + org.testcontainerstestcontainers-junit-jupitertest org.springframework.bootspring-boot-maven-plugin diff --git a/job-service/src/test/java/com/devhire/job/repository/JobRepositoryIT.java b/job-service/src/test/java/com/devhire/job/repository/JobRepositoryIT.java index b75eaffe..d155bd2b 100644 --- a/job-service/src/test/java/com/devhire/job/repository/JobRepositoryIT.java +++ b/job-service/src/test/java/com/devhire/job/repository/JobRepositoryIT.java @@ -4,13 +4,13 @@ import com.devhire.job.entity.JobStatus; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; +import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.domain.PageRequest; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.postgresql.PostgreSQLContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -28,7 +28,7 @@ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class JobRepositoryIT { @Container - static final PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:17-alpine"); + static final PostgreSQLContainer postgres = new PostgreSQLContainer("postgres:17-alpine"); @Autowired private JobRepository jobRepository; diff --git a/notification-service/Dockerfile b/notification-service/Dockerfile index 3c2d53b1..35ab27ad 100644 --- a/notification-service/Dockerfile +++ b/notification-service/Dockerfile @@ -1,4 +1,4 @@ -FROM maven:3.9.12-eclipse-temurin-21 AS build +FROM maven:3.9.14-eclipse-temurin-25 AS build WORKDIR /workspace ARG SERVICE_NAME=notification-service COPY pom.xml . @@ -17,7 +17,7 @@ COPY common-lib/src common-lib/src COPY ${SERVICE_NAME}/src ${SERVICE_NAME}/src RUN mvn -B -T1 -pl ${SERVICE_NAME} -am package -DskipTests -FROM eclipse-temurin:21-jre-alpine +FROM eclipse-temurin:25-jre-alpine ARG SERVICE_NAME=notification-service ARG BUILD_VERSION=0.4.0-SNAPSHOT ARG VCS_REF=local diff --git a/notification-service/pom.xml b/notification-service/pom.xml index 53679553..189f746c 100644 --- a/notification-service/pom.xml +++ b/notification-service/pom.xml @@ -1,4 +1,4 @@ - + @@ -19,8 +19,8 @@ org.springframework.bootspring-boot-starter-actuator org.springframework.bootspring-boot-starter-mail org.springframework.cloudspring-cloud-starter-openfeign - org.springframework.kafkaspring-kafka - org.flywaydbflyway-core + org.springframework.bootspring-boot-starter-kafka + org.springframework.bootspring-boot-starter-flyway org.flywaydbflyway-database-postgresql org.postgresqlpostgresqlruntime org.springdocspringdoc-openapi-starter-webmvc-ui${springdoc.version} @@ -32,12 +32,14 @@ io.jsonwebtokenjjwt-jackson${jjwt.version}runtime org.springframework.bootspring-boot-starter-data-redis org.springframework.bootspring-boot-starter-testtest - org.testcontainerspostgresqltest - org.testcontainersjunit-jupitertest - org.testcontainerskafkatest + org.springframework.bootspring-boot-starter-data-jpa-testtest + org.springframework.bootspring-boot-starter-flyway-testtest + org.testcontainerstestcontainers-postgresqltest + org.testcontainerstestcontainers-junit-jupitertest + org.testcontainerstestcontainers-kafkatest org.springframework.kafkaspring-kafka-testtest org.awaitilityawaitilitytest - net.jqwikjqwik1.9.2test + net.jqwikjqwik1.10.1test org.springframework.bootspring-boot-maven-plugin diff --git a/notification-service/src/test/java/com/devhire/notification/integration/CacheInvalidationIntegrationTest.java b/notification-service/src/test/java/com/devhire/notification/integration/CacheInvalidationIntegrationTest.java index 2f931e7a..7b72a8b9 100644 --- a/notification-service/src/test/java/com/devhire/notification/integration/CacheInvalidationIntegrationTest.java +++ b/notification-service/src/test/java/com/devhire/notification/integration/CacheInvalidationIntegrationTest.java @@ -12,7 +12,7 @@ import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.StringRedisTemplate; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.KafkaContainer; +import org.testcontainers.kafka.ConfluentKafkaContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; @@ -43,7 +43,7 @@ class CacheInvalidationIntegrationTest { .withExposedPorts(6379); @Container - static final KafkaContainer KAFKA = new KafkaContainer( + static final ConfluentKafkaContainer KAFKA = new ConfluentKafkaContainer( DockerImageName.parse("confluentinc/cp-kafka:7.6.0")); private LettuceConnectionFactory connectionFactory; diff --git a/notification-service/src/test/java/com/devhire/notification/integration/KafkaNotificationPipelineIntegrationTest.java b/notification-service/src/test/java/com/devhire/notification/integration/KafkaNotificationPipelineIntegrationTest.java index aa325988..a36b171a 100644 --- a/notification-service/src/test/java/com/devhire/notification/integration/KafkaNotificationPipelineIntegrationTest.java +++ b/notification-service/src/test/java/com/devhire/notification/integration/KafkaNotificationPipelineIntegrationTest.java @@ -16,8 +16,8 @@ import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.KafkaContainer; -import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.kafka.ConfluentKafkaContainer; +import org.testcontainers.postgresql.PostgreSQLContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; @@ -47,11 +47,11 @@ class KafkaNotificationPipelineIntegrationTest { .withExposedPorts(6379); @Container - static final KafkaContainer KAFKA = new KafkaContainer( + static final ConfluentKafkaContainer KAFKA = new ConfluentKafkaContainer( DockerImageName.parse("confluentinc/cp-kafka:7.6.0")); @Container - static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>( + static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer( DockerImageName.parse("postgres:17-alpine")) .withDatabaseName("notification_test") .withUsername("test") diff --git a/notification-service/src/test/java/com/devhire/notification/repository/NotificationRepositoryIT.java b/notification-service/src/test/java/com/devhire/notification/repository/NotificationRepositoryIT.java index d8ec7ae8..95017e06 100644 --- a/notification-service/src/test/java/com/devhire/notification/repository/NotificationRepositoryIT.java +++ b/notification-service/src/test/java/com/devhire/notification/repository/NotificationRepositoryIT.java @@ -3,12 +3,12 @@ import com.devhire.notification.entity.Notification; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; +import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.postgresql.PostgreSQLContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -22,7 +22,7 @@ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class NotificationRepositoryIT { @Container - static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>("postgres:17-alpine"); + static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer("postgres:17-alpine"); @DynamicPropertySource static void datasource(DynamicPropertyRegistry registry) { diff --git a/pom.xml b/pom.xml index 16306a98..9de1f1ed 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,4 @@ - + @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.14 + 4.0.6 @@ -35,14 +35,18 @@ 21 21 - 2025.0.2 - 4.1.133.Final - 10.1.54 + 2025.1.1 + 2.21.4 + 3.1.4 + 4.2.15.Final + 11.0.22 + 4.0.6 + 1.6.0 42.7.11 - 1.84 + 1.85 0.12.6 - 2.8.9 - 1.20.6 + 3.0.3 + 2.0.5 1.6.3 1.4.1 0.35 @@ -71,6 +75,11 @@ bcprov-jdk18on ${bouncycastle.version} + + commons-fileupload + commons-fileupload + ${commons-fileupload.version} + @@ -112,7 +121,7 @@ org.jacoco jacoco-maven-plugin - 0.8.14 + 0.8.15 diff --git a/user-service/Dockerfile b/user-service/Dockerfile index 90818cf1..833f5639 100644 --- a/user-service/Dockerfile +++ b/user-service/Dockerfile @@ -1,4 +1,4 @@ -FROM maven:3.9.12-eclipse-temurin-21 AS build +FROM maven:3.9.14-eclipse-temurin-25 AS build WORKDIR /workspace ARG SERVICE_NAME=user-service COPY pom.xml . @@ -17,7 +17,7 @@ COPY common-lib/src common-lib/src COPY ${SERVICE_NAME}/src ${SERVICE_NAME}/src RUN mvn -B -T1 -pl ${SERVICE_NAME} -am package -DskipTests -FROM eclipse-temurin:21-jre-alpine +FROM eclipse-temurin:25-jre-alpine ARG SERVICE_NAME=user-service ARG BUILD_VERSION=0.4.0-SNAPSHOT ARG VCS_REF=local diff --git a/user-service/pom.xml b/user-service/pom.xml index 8e21ac67..dbaba63a 100644 --- a/user-service/pom.xml +++ b/user-service/pom.xml @@ -16,8 +16,8 @@ org.springframework.bootspring-boot-starter-validation org.springframework.bootspring-boot-starter-data-jpa org.springframework.bootspring-boot-starter-actuator - org.springframework.kafkaspring-kafka - org.flywaydbflyway-core + org.springframework.bootspring-boot-starter-kafka + org.springframework.bootspring-boot-starter-flyway org.flywaydbflyway-database-postgresql org.postgresqlpostgresqlruntime org.springdocspringdoc-openapi-starter-webmvc-ui${springdoc.version} @@ -25,8 +25,10 @@ io.micrometermicrometer-tracing-bridge-otel io.opentelemetryopentelemetry-exporter-otlp org.springframework.bootspring-boot-starter-testtest - org.testcontainerspostgresqltest - org.testcontainersjunit-jupitertest + org.springframework.bootspring-boot-starter-data-jpa-testtest + org.springframework.bootspring-boot-starter-flyway-testtest + org.testcontainerstestcontainers-postgresqltest + org.testcontainerstestcontainers-junit-jupitertest org.springframework.bootspring-boot-maven-plugin diff --git a/user-service/src/test/java/com/devhire/user/repository/UserProfileRepositoryIT.java b/user-service/src/test/java/com/devhire/user/repository/UserProfileRepositoryIT.java index 949f01e3..ebb5c3f1 100644 --- a/user-service/src/test/java/com/devhire/user/repository/UserProfileRepositoryIT.java +++ b/user-service/src/test/java/com/devhire/user/repository/UserProfileRepositoryIT.java @@ -4,12 +4,12 @@ import com.devhire.user.entity.UserProfile; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; +import org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.postgresql.PostgreSQLContainer; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -23,7 +23,7 @@ @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class UserProfileRepositoryIT { @Container - static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer<>("postgres:17-alpine"); + static final PostgreSQLContainer POSTGRES = new PostgreSQLContainer("postgres:17-alpine"); @DynamicPropertySource static void datasource(DynamicPropertyRegistry registry) {