Compare commits

..
Author SHA1 Message Date
github-actions[bot] 0444ad5a5d chore: bump api version to 8 [skip ci] 2026-02-27 18:10:34 +00:00
CopilotGitHubcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>RMCamposrmcampos
89eb15d714 Upgrade backend to Spring Boot 4.0.3 and Java 25 (#20)
* Initial plan

* feat: upgrade to Spring Boot 4.0.3 and Java 25

Co-authored-by: RMCampos <2219519+RMCampos@users.noreply.github.com>

* chore: fix google check style issues and drop unused annotations

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: RMCampos <2219519+RMCampos@users.noreply.github.com>
Co-authored-by: Ricardo Campos <ricardompcampos@gmail.com>
2026-02-27 15:10:05 -03:00
rmcampos 08ed7c485e chore: drop claude from repo 2026-02-27 13:58:51 -03:00
rmcampos cf598c0971 chore: bump frontend dependencies version 2026-02-27 13:52:52 -03:00
35 changed files with 375 additions and 571 deletions
-44
View File
@@ -1,44 +0,0 @@
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]
# Optional: Only run on specific file changes
# paths:
# - "src/**/*.ts"
# - "src/**/*.tsx"
# - "src/**/*.js"
# - "src/**/*.jsx"
jobs:
claude-review:
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
# github.event.pull_request.user.login == 'new-developer' ||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
-50
View File
@@ -1,50 +0,0 @@
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
# prompt: 'Update the pull request description to include a summary of changes.'
# Optional: Add claude_args to customize behavior and configuration
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr:*)'
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
java-version: '25'
cache: 'maven'
- name: Increment version in pom.xml
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
java-version: '25'
cache: 'maven'
- name: Run Check Style
-113
View File
@@ -1,113 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
### Frontend (React/TypeScript)
```bash
cd client
npm start # Start development server on port 5000
npm run build # Build production bundle (TypeScript compilation + Vite build)
npm run preview # Preview production build
npm test # Run Vitest tests
npm run test:coverage # Run tests with coverage report
npm run lint # Run ESLint
npm run lint:fix # Run ESLint with auto-fix
```
### Backend (Java/Spring Boot)
```bash
cd server
./mvnw spring-boot:run # Start development server
./mvnw clean compile # Compile Java sources
./mvnw test # Run unit tests only
./mvnw clean verify -Ptests # Run all tests (unit + integration) with coverage
./mvnw spring-boot:build-image # Build Docker image
./mvnw clean verify -Pnative # Build GraalVM native image
```
### Docker Development Environment
```bash
bash tools/run-docker-db.sh # Start PostgreSQL database
bash tools/run-docker-server.sh # Start backend in Docker
bash tools/run-docker-client.sh # Start frontend in Docker
bash tools/check-frontend.sh # Run frontend quality checks
bash tools/check-backend.sh # Run backend quality checks
```
## Architecture
### Monorepo Structure
- `client/` - React TypeScript frontend (Vite + Vitest)
- `server/` - Java Spring Boot REST API
- `tools/` - Development and deployment scripts
- `docker-compose.dev.yml` / `docker-compose.prod.yml` - Multi-service development and production environments
- `Taskfile.yml` - Task automation for docker builds and workflows
### Frontend Architecture (client/)
- **Framework**: React 19 with React Router v7
- **State Management**: React Context API for authentication and sidebar state
- **Authentication**: JWT tokens stored in localStorage with automatic refresh (2-minute intervals)
- **Routing**: Dynamic router configuration based on auth status (signed vs not-signed routes)
- **Internationalization**: i18next with support for English, Portuguese, Russian, Spanish
- **Styling**: Bootstrap 5 + SCSS with dark/light theme support
- **Testing**: Vitest with React Testing Library and coverage reporting
- **API Layer**: Centralized API service in `src/api-service/api.ts` with automatic auth headers
### Backend Architecture (server/)
- **Framework**: Spring Boot 3.5.9 with Java 21
- **Security**: Spring Security with JWT authentication
- **Database**: PostgreSQL with JPA/Hibernate and Flyway migrations
- **Testing**: Separate unit tests and integration tests with 75% coverage requirement
- **Build Options**: Traditional JAR or GraalVM native image compilation
### Key Components
**Authentication Flow:**
1. User credentials → `/auth/sign-in` endpoint
2. Server responds with JWT token and user data
3. Token stored in localStorage, added to all API requests via Authorization header
4. Automatic token refresh every 2 minutes via `/rest/user-sessions/refresh`
5. Protected routes wrap authenticated pages, redirect on auth failure
**Database Schema:**
- Core entities: Users, Tasks, Notes, Task URLs, Notes URLs
- User management with password reset functionality
- Task completion tracking and user statistics
## Development Workflow
### Manual Setup
1. Start database: `bash tools/run-docker-db.sh`
2. Start backend: `bash tools/run-docker-server.sh` or `cd server && ./mvnw spring-boot:run`
3. Start frontend: `bash tools/run-docker-client.sh` or `cd client && npm start`
4. Access app at http://localhost:5000
### Using Taskfile
Alternatively, use the Taskfile.yml for automated workflows:
```bash
task dev-run # Start development environment (docker-compose.dev.yml)
task prod-up # Start production environment (docker-compose.prod.yml)
task docker-build-api # Build server Docker image
task docker-build-web # Build app Docker image
task -l # List all available tasks
```
### Quality Checks
Always run quality checks before submitting changes:
- Frontend: `bash tools/check-frontend.sh`
- Backend: `bash tools/check-backend.sh`
## Testing
### Frontend Testing
- **Framework**: Vitest + React Testing Library
- **Coverage**: Generated in `client/coverage/` directory
- **Run**: `cd client && npm test` or `npm run test:coverage`
### Backend Testing
- **Unit Tests**: Standard JUnit tests, run with `./mvnw test`
- **Integration Tests**: Files ending in `*IntTest.java`, require database
- **Coverage**: JaCoCo reports, 75% minimum requirement
- **Full Test Suite**: `./mvnw clean verify -Ptests` (includes checkstyle, coverage)
+302 -259
View File
@@ -10,12 +10,12 @@
"license": "GPL-3.0-only",
"dependencies": {
"@popperjs/core": "^2.11.8",
"@types/node": "^25.2.3",
"@types/node": "^25.3.2",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.4",
"bootstrap": "^5.3.8",
"dompurify": "^3.3.1",
"i18next": "^25.8.6",
"i18next": "^25.8.13",
"react": "^19.2.4",
"react-bootstrap": "^2.10.10",
"react-bootstrap-icons": "^1.11.6",
@@ -24,7 +24,7 @@
"react-dom": "^19.2.4",
"react-i18next": "^16.5.4",
"react-markdown": "^10.1.0",
"react-router": "^7.13.0",
"react-router": "^7.13.1",
"react-router-bootstrap": "^0.26.3",
"remark-gfm": "^4.0.1",
"typescript": "^5.9.3",
@@ -32,9 +32,9 @@
},
"devDependencies": {
"@eslint/compat": "^2.0.2",
"@eslint/eslintrc": "^3.3.3",
"@eslint/eslintrc": "^3.3.4",
"@eslint/js": "^9.39.2",
"@stylistic/eslint-plugin": "^5.8.0",
"@stylistic/eslint-plugin": "^5.9.0",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
@@ -45,16 +45,16 @@
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jsdoc": "^62.5.4",
"eslint-plugin-n": "^17.23.2",
"eslint-plugin-jsdoc": "^62.7.1",
"eslint-plugin-n": "^17.24.0",
"eslint-plugin-promise": "^7.2.1",
"eslint-plugin-react": "^7.37.5",
"globals": "^17.3.0",
"jsdom": "^28.0.0",
"jsdom": "^28.1.0",
"prettier": "^3.8.1",
"sass": "^1.97.3",
"source-map-support": "^0.5.21",
"typescript-eslint": "^8.55.0",
"typescript-eslint": "^8.56.1",
"vitest": "^4.0.18"
}
},
@@ -73,23 +73,26 @@
"license": "MIT"
},
"node_modules/@asamuzakjp/css-color": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz",
"integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.0.1.tgz",
"integrity": "sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@csstools/css-calc": "^3.0.0",
"@csstools/css-color-parser": "^4.0.1",
"@csstools/css-calc": "^3.1.1",
"@csstools/css-color-parser": "^4.0.2",
"@csstools/css-parser-algorithms": "^4.0.0",
"@csstools/css-tokenizer": "^4.0.0",
"lru-cache": "^11.2.5"
"lru-cache": "^11.2.6"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
}
},
"node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
"version": "11.2.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz",
"integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==",
"version": "11.2.6",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz",
"integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
@@ -97,9 +100,9 @@
}
},
"node_modules/@asamuzakjp/dom-selector": {
"version": "6.7.8",
"resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.8.tgz",
"integrity": "sha512-stisC1nULNc9oH5lakAj8MH88ZxeGxzyWNDfbdCxvJSJIvDsHNZqYvscGTgy/ysgXWLJPt6K/4t0/GjvtKcFJQ==",
"version": "6.8.1",
"resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz",
"integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -107,13 +110,13 @@
"bidi-js": "^1.0.3",
"css-tree": "^3.1.0",
"is-potential-custom-element-name": "^1.0.1",
"lru-cache": "^11.2.5"
"lru-cache": "^11.2.6"
}
},
"node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": {
"version": "11.2.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz",
"integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==",
"version": "11.2.6",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz",
"integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
@@ -409,10 +412,23 @@
"node": ">=18"
}
},
"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": "6.0.1",
"resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.1.tgz",
"integrity": "sha512-NmXRccUJMk2AWA5A7e5a//3bCIMyOu2hAtdRYrhPPHjDxINuCwX1w6rnIZ4xjLcp0ayv6h8Pc3X0eJUGiAAXHQ==",
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz",
"integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==",
"dev": true,
"funding": [
{
@@ -430,9 +446,9 @@
}
},
"node_modules/@csstools/css-calc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.0.0.tgz",
"integrity": "sha512-q4d82GTl8BIlh/dTnVsWmxnbWJeb3kiU8eUH71UxlxnS+WIaALmtzTL8gR15PkYOexMQYVk0CO4qIG93C1IvPA==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz",
"integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==",
"dev": true,
"funding": [
{
@@ -454,9 +470,9 @@
}
},
"node_modules/@csstools/css-color-parser": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.1.tgz",
"integrity": "sha512-vYwO15eRBEkeF6xjAno/KQ61HacNhfQuuU/eGwH67DplL0zD5ZixUa563phQvUelA07yDczIXdtmYojCphKJcw==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz",
"integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==",
"dev": true,
"funding": [
{
@@ -470,8 +486,8 @@
],
"license": "MIT",
"dependencies": {
"@csstools/color-helpers": "^6.0.1",
"@csstools/css-calc": "^3.0.0"
"@csstools/color-helpers": "^6.0.2",
"@csstools/css-calc": "^3.1.1"
},
"engines": {
"node": ">=20.19.0"
@@ -505,9 +521,9 @@
}
},
"node_modules/@csstools/css-syntax-patches-for-csstree": {
"version": "1.0.26",
"resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.26.tgz",
"integrity": "sha512-6boXK0KkzT5u5xOgF6TKB+CLq9SOpEGmkZw0g5n9/7yg85wab3UzSxB8TxhLJ31L4SGJ6BCFRw/iftTha1CJXA==",
"version": "1.0.28",
"resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.28.tgz",
"integrity": "sha512-1NRf1CUBjnr3K7hu8BLxjQrKCxEe8FP/xmPTenAxCRZWVLbmGotkFvG9mfNpjA6k7Bw1bw4BilZq9cu19RA5pg==",
"dev": true,
"funding": [
{
@@ -1102,20 +1118,20 @@
}
},
"node_modules/@eslint/eslintrc": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
"integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz",
"integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ajv": "^6.12.4",
"ajv": "^6.14.0",
"debug": "^4.3.2",
"espree": "^10.0.1",
"globals": "^14.0.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
"js-yaml": "^4.1.1",
"minimatch": "^3.1.2",
"minimatch": "^3.1.3",
"strip-json-comments": "^3.1.1"
},
"engines": {
@@ -2137,14 +2153,14 @@
"license": "MIT"
},
"node_modules/@stylistic/eslint-plugin": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.8.0.tgz",
"integrity": "sha512-WNPVF/FfBAjyi3OA7gok8swRiImNLKI4dmV3iK/GC/0xSJR7eCzBFsw9hLZVgb1+MYNLy7aDsjohxN1hA/FIfQ==",
"version": "5.9.0",
"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.9.0.tgz",
"integrity": "sha512-FqqSkvDMYJReydrMhlugc71M76yLLQWNfmGq+SIlLa7N3kHp8Qq8i2PyWrVNAfjOyOIY+xv9XaaYwvVW7vroMA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/types": "^8.54.0",
"@typescript-eslint/types": "^8.56.0",
"eslint-visitor-keys": "^4.2.1",
"espree": "^10.4.0",
"estraverse": "^5.3.0",
@@ -2154,7 +2170,7 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"peerDependencies": {
"eslint": ">=9.0.0"
"eslint": "^9.0.0 || ^10.0.0"
}
},
"node_modules/@swc/helpers": {
@@ -2495,12 +2511,12 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "25.2.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz",
"integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==",
"version": "25.3.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.2.tgz",
"integrity": "sha512-RpV6r/ij22zRRdyBPcxDeKAzH43phWVKEjL2iksqo1Vz3CuBUrgmPpPhALKiRfU7OMCmeeO9vECBMsV0hMTG8Q==",
"license": "MIT",
"dependencies": {
"undici-types": "~7.16.0"
"undici-types": "~7.18.0"
}
},
"node_modules/@types/prop-types": {
@@ -2601,15 +2617,79 @@
"dev": true,
"license": "MIT"
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz",
"integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==",
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz",
"integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.55.0",
"@typescript-eslint/types": "^8.55.0",
"@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.56.1",
"@typescript-eslint/type-utils": "8.56.1",
"@typescript-eslint/utils": "8.56.1",
"@typescript-eslint/visitor-keys": "8.56.1",
"ignore": "^7.0.5",
"natural-compare": "^1.4.0",
"ts-api-utils": "^2.4.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.56.1",
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz",
"integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.56.1",
"@typescript-eslint/types": "8.56.1",
"@typescript-eslint/typescript-estree": "8.56.1",
"@typescript-eslint/visitor-keys": "8.56.1",
"debug": "^4.4.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz",
"integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.56.1",
"@typescript-eslint/types": "^8.56.1",
"debug": "^4.4.3"
},
"engines": {
@@ -2624,14 +2704,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz",
"integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==",
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz",
"integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.55.0",
"@typescript-eslint/visitor-keys": "8.55.0"
"@typescript-eslint/types": "8.56.1",
"@typescript-eslint/visitor-keys": "8.56.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2642,9 +2722,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz",
"integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==",
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz",
"integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2658,10 +2738,35 @@
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz",
"integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.56.1",
"@typescript-eslint/typescript-estree": "8.56.1",
"@typescript-eslint/utils": "8.56.1",
"debug": "^4.4.3",
"ts-api-utils": "^2.4.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz",
"integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==",
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz",
"integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2673,18 +2778,18 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz",
"integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==",
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz",
"integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.55.0",
"@typescript-eslint/tsconfig-utils": "8.55.0",
"@typescript-eslint/types": "8.55.0",
"@typescript-eslint/visitor-keys": "8.55.0",
"@typescript-eslint/project-service": "8.56.1",
"@typescript-eslint/tsconfig-utils": "8.56.1",
"@typescript-eslint/types": "8.56.1",
"@typescript-eslint/visitor-keys": "8.56.1",
"debug": "^4.4.3",
"minimatch": "^9.0.5",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
"tinyglobby": "^0.2.15",
"ts-api-utils": "^2.4.0"
@@ -2700,27 +2805,40 @@
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "18 || 20 || >=22"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz",
"integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
"balanced-match": "^4.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"version": "10.2.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz",
"integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==",
"dev": true,
"license": "ISC",
"license": "BlueOak-1.0.0",
"dependencies": {
"brace-expansion": "^2.0.1"
"brace-expansion": "^5.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -2739,15 +2857,17 @@
"node": ">=10"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz",
"integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==",
"node_modules/@typescript-eslint/utils": {
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz",
"integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.55.0",
"eslint-visitor-keys": "^4.2.1"
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.56.1",
"@typescript-eslint/types": "8.56.1",
"@typescript-eslint/typescript-estree": "8.56.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -2755,6 +2875,41 @@
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz",
"integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.56.1",
"eslint-visitor-keys": "^5.0.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
"integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^20.19.0 || ^22.13.0 || >=24"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/@ungap/structured-clone": {
@@ -2959,9 +3114,9 @@
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
"integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3666,25 +3821,25 @@
"license": "MIT"
},
"node_modules/cssstyle": {
"version": "5.3.7",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz",
"integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.1.0.tgz",
"integrity": "sha512-Ml4fP2UT2K3CUBQnVlbdV/8aFDdlY69E+YnwJM+3VUWl08S3J8c8aRuJqCkD9Py8DHZ7zNNvsfKl8psocHZEFg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@asamuzakjp/css-color": "^4.1.1",
"@csstools/css-syntax-patches-for-csstree": "^1.0.21",
"@asamuzakjp/css-color": "^5.0.0",
"@csstools/css-syntax-patches-for-csstree": "^1.0.28",
"css-tree": "^3.1.0",
"lru-cache": "^11.2.4"
"lru-cache": "^11.2.6"
},
"engines": {
"node": ">=20"
}
},
"node_modules/cssstyle/node_modules/lru-cache": {
"version": "11.2.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz",
"integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==",
"version": "11.2.6",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz",
"integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
@@ -4550,9 +4705,9 @@
}
},
"node_modules/eslint-plugin-jsdoc": {
"version": "62.5.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-62.5.4.tgz",
"integrity": "sha512-U+Q5ppErmC17VFQl542eBIaXcuq975BzoIHBXyx7UQx/i4gyHXxPiBkonkuxWyFA98hGLALLUuD+NJcXqSGKxg==",
"version": "62.7.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-62.7.1.tgz",
"integrity": "sha512-4Zvx99Q7d1uggYBUX/AIjvoyqXhluGbbKrRmG8SQTLprPFg6fa293tVJH1o1GQwNe3lUydd8ZHzn37OaSncgSQ==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -4567,7 +4722,7 @@
"html-entities": "^2.6.0",
"object-deep-merge": "^2.0.0",
"parse-imports-exports": "^0.2.4",
"semver": "^7.7.3",
"semver": "^7.7.4",
"spdx-expression-parse": "^4.0.0",
"to-valid-identifier": "^1.0.0"
},
@@ -4575,7 +4730,7 @@
"node": "^20.19.0 || ^22.13.0 || >=24"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0"
}
},
"node_modules/eslint-plugin-jsdoc/node_modules/eslint-visitor-keys": {
@@ -4610,9 +4765,9 @@
}
},
"node_modules/eslint-plugin-jsdoc/node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
"dev": true,
"license": "ISC",
"bin": {
@@ -4623,9 +4778,9 @@
}
},
"node_modules/eslint-plugin-n": {
"version": "17.23.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.23.2.tgz",
"integrity": "sha512-RhWBeb7YVPmNa2eggvJooiuehdL76/bbfj/OJewyoGT80qn5PXdz8zMOTO6YHOsI7byPt7+Ighh/i/4a5/v7hw==",
"version": "17.24.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.24.0.tgz",
"integrity": "sha512-/gC7/KAYmfNnPNOb3eu8vw+TdVnV0zhdQwexsw6FLXbhzroVj20vRn2qL8lDWDGnAQ2J8DhdfvXxX9EoxvERvw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5447,9 +5602,9 @@
}
},
"node_modules/i18next": {
"version": "25.8.6",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.8.6.tgz",
"integrity": "sha512-HsS6p2yr/Vo5EPljWuBJ9OxKVFok2Q/Oa6PvFTpv2bMcDt2sQMOnKDQ7FTDDdME+3d1YULQjKj7aVSZP1bCouQ==",
"version": "25.8.13",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.8.13.tgz",
"integrity": "sha512-E0vzjBY1yM+nsFrtgkjLhST2NBkirkvOVoQa0MSldhsuZ3jUge7ZNpuwG0Cfc74zwo5ZwRzg3uOgT+McBn32iA==",
"funding": [
{
"type": "individual",
@@ -6323,16 +6478,17 @@
}
},
"node_modules/jsdom": {
"version": "28.0.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.0.0.tgz",
"integrity": "sha512-KDYJgZ6T2TKdU8yBfYueq5EPG/EylMsBvCaenWMJb2OXmjgczzwveRCoJ+Hgj1lXPDyasvrgneSn4GBuR1hYyA==",
"version": "28.1.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.1.0.tgz",
"integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==",
"dev": true,
"license": "MIT",
"dependencies": {
"@acemir/cssom": "^0.9.31",
"@asamuzakjp/dom-selector": "^6.7.6",
"@asamuzakjp/dom-selector": "^6.8.1",
"@bramus/specificity": "^2.4.2",
"@exodus/bytes": "^1.11.0",
"cssstyle": "^5.3.7",
"cssstyle": "^6.0.1",
"data-urls": "^7.0.0",
"decimal.js": "^10.6.0",
"html-encoding-sniffer": "^6.0.0",
@@ -6343,7 +6499,7 @@
"saxes": "^6.0.0",
"symbol-tree": "^3.2.4",
"tough-cookie": "^6.0.0",
"undici": "^7.20.0",
"undici": "^7.21.0",
"w3c-xmlserializer": "^5.0.0",
"webidl-conversions": "^8.0.1",
"whatwg-mimetype": "^5.0.0",
@@ -7473,9 +7629,9 @@
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -8230,9 +8386,9 @@
}
},
"node_modules/react-router": {
"version": "7.13.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz",
"integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==",
"version": "7.13.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.1.tgz",
"integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==",
"license": "MIT",
"dependencies": {
"cookie": "^1.0.1",
@@ -9491,16 +9647,16 @@
}
},
"node_modules/typescript-eslint": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.55.0.tgz",
"integrity": "sha512-HE4wj+r5lmDVS9gdaN0/+iqNvPZwGfnJ5lZuz7s5vLlg9ODw0bIiiETaios9LvFI1U94/VBXGm3CB2Y5cNFMpw==",
"version": "8.56.1",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.1.tgz",
"integrity": "sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.55.0",
"@typescript-eslint/parser": "8.55.0",
"@typescript-eslint/typescript-estree": "8.55.0",
"@typescript-eslint/utils": "8.55.0"
"@typescript-eslint/eslint-plugin": "8.56.1",
"@typescript-eslint/parser": "8.56.1",
"@typescript-eslint/typescript-estree": "8.56.1",
"@typescript-eslint/utils": "8.56.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -9510,123 +9666,10 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz",
"integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.55.0",
"@typescript-eslint/type-utils": "8.55.0",
"@typescript-eslint/utils": "8.55.0",
"@typescript-eslint/visitor-keys": "8.55.0",
"ignore": "^7.0.5",
"natural-compare": "^1.4.0",
"ts-api-utils": "^2.4.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.55.0",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz",
"integrity": "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.55.0",
"@typescript-eslint/typescript-estree": "8.55.0",
"@typescript-eslint/utils": "8.55.0",
"debug": "^4.4.3",
"ts-api-utils": "^2.4.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz",
"integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.55.0",
"@typescript-eslint/types": "8.55.0",
"@typescript-eslint/typescript-estree": "8.55.0",
"@typescript-eslint/visitor-keys": "8.55.0",
"debug": "^4.4.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": {
"version": "8.55.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz",
"integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.55.0",
"@typescript-eslint/types": "8.55.0",
"@typescript-eslint/typescript-estree": "8.55.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <6.0.0"
}
},
"node_modules/typescript-eslint/node_modules/ignore": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/unbox-primitive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
@@ -9662,9 +9705,9 @@
}
},
"node_modules/undici": {
"version": "7.20.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.20.0.tgz",
"integrity": "sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==",
"version": "7.22.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz",
"integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -9672,9 +9715,9 @@
}
},
"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.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"license": "MIT"
},
"node_modules/unified": {
+9 -9
View File
@@ -13,12 +13,12 @@
"private": true,
"dependencies": {
"@popperjs/core": "^2.11.8",
"@types/node": "^25.2.3",
"@types/node": "^25.3.2",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.4",
"bootstrap": "^5.3.8",
"dompurify": "^3.3.1",
"i18next": "^25.8.6",
"i18next": "^25.8.13",
"react": "^19.2.4",
"react-bootstrap": "^2.10.10",
"react-bootstrap-icons": "^1.11.6",
@@ -27,7 +27,7 @@
"react-dom": "^19.2.4",
"react-i18next": "^16.5.4",
"react-markdown": "^10.1.0",
"react-router": "^7.13.0",
"react-router": "^7.13.1",
"react-router-bootstrap": "^0.26.3",
"remark-gfm": "^4.0.1",
"typescript": "^5.9.3",
@@ -63,9 +63,9 @@
},
"devDependencies": {
"@eslint/compat": "^2.0.2",
"@eslint/eslintrc": "^3.3.3",
"@eslint/eslintrc": "^3.3.4",
"@eslint/js": "^9.39.2",
"@stylistic/eslint-plugin": "^5.8.0",
"@stylistic/eslint-plugin": "^5.9.0",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
@@ -76,16 +76,16 @@
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jsdoc": "^62.5.4",
"eslint-plugin-n": "^17.23.2",
"eslint-plugin-jsdoc": "^62.7.1",
"eslint-plugin-n": "^17.24.0",
"eslint-plugin-promise": "^7.2.1",
"eslint-plugin-react": "^7.37.5",
"globals": "^17.3.0",
"jsdom": "^28.0.0",
"jsdom": "^28.1.0",
"prettier": "^3.8.1",
"sass": "^1.97.3",
"source-map-support": "^0.5.21",
"typescript-eslint": "^8.55.0",
"typescript-eslint": "^8.56.1",
"vitest": "^4.0.18"
}
}
+1 -1
View File
@@ -39,7 +39,7 @@ services:
ports:
- "8585:8585"
- "5005:5005"
image: maven:3.9.9-eclipse-temurin-21
image: maven:3.9.9-eclipse-temurin-25
entrypoint: './mvnw -ntp spring-boot:run -Dspring-boot.run.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:5005" -Dmaven.plugin.validation=VERBOSE'
working_dir: /app
volumes:
+15 -15
View File
@@ -5,13 +5,13 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.9</version>
<version>4.0.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>br.com.tasknoteapp</groupId>
<artifactId>server</artifactId>
<version>7</version>
<version>8</version>
<name>tasknote-api</name>
<description>Java backend REST API to serve TaskNote frontend client</description>
@@ -37,7 +37,7 @@
<!-- Properties -->
<properties>
<java.version>21</java.version>
<java.version>25</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<skip.integration.tests>true</skip.integration.tests>
@@ -80,7 +80,11 @@
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-restclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -106,23 +110,19 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-flyway</artifactId>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<artifactId>spring-boot-starter-test-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
@@ -153,8 +153,8 @@
<build>
<plugins>
<plugin>
<groupId>org.hibernate.orm.tooling</groupId>
<artifactId>hibernate-enhance-maven-plugin</artifactId>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-maven-plugin</artifactId>
<version>${hibernate.version}</version>
<executions>
<execution>
@@ -5,7 +5,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -23,8 +22,7 @@ public class CorsConfig implements WebMvcConfigurer {
*
* @param registry CorsRegistry instance.
*/
@SuppressWarnings("null")
public void addCorsMappings(@NonNull CorsRegistry registry) {
public void addCorsMappings(CorsRegistry registry) {
if (allowedOrigins != null && allowedOrigins.length > 0) {
logger.info("CORS policy allowed origins: {}", Arrays.asList(allowedOrigins));
@@ -10,7 +10,6 @@ import jakarta.validation.Valid;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
@@ -49,7 +48,7 @@ public class NoteController {
* @throws NoteNotFoundException when note not found.
*/
@GetMapping("/{id}")
public NoteResponse getTaskById(@NonNull @PathVariable Long id) {
public NoteResponse getTaskById(@PathVariable Long id) {
return noteService.getNoteById(id);
}
@@ -63,7 +62,7 @@ public class NoteController {
*/
@PatchMapping("/{id}")
public ResponseEntity<NoteResponse> patchNote(
@PathVariable @NonNull Long id, @RequestBody @Valid NotePatchRequest noteRequest) {
@PathVariable Long id, @RequestBody @Valid NotePatchRequest noteRequest) {
return ResponseEntity.ok(noteService.patchNote(id, noteRequest));
}
@@ -88,7 +87,7 @@ public class NoteController {
* @throws NoteNotFoundException when note not found.
*/
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteNote(@NonNull @PathVariable Long id) {
public ResponseEntity<Void> deleteNote(@PathVariable Long id) {
noteService.deleteNote(id);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
@@ -9,7 +9,6 @@ import jakarta.validation.Valid;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
@@ -48,7 +47,7 @@ public class TaskController {
* @throws TaskNotFoundException when task not found.
*/
@GetMapping("/{id}")
public TaskResponse getTaskById(@NonNull @PathVariable Long id) {
public TaskResponse getTaskById(@PathVariable Long id) {
return taskService.getTaskById(id);
}
@@ -62,7 +61,7 @@ public class TaskController {
*/
@PatchMapping("/{id}")
public ResponseEntity<TaskResponse> patchTask(
@PathVariable @NonNull Long id, @RequestBody @Valid TaskPatchRequest taskRequest) {
@PathVariable Long id, @RequestBody @Valid TaskPatchRequest taskRequest) {
return ResponseEntity.ok(taskService.patchTask(id, taskRequest));
}
@@ -86,7 +85,7 @@ public class TaskController {
* @throws TaskNotFoundException when task not found.
*/
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteTask(@NonNull @PathVariable Long id) {
public ResponseEntity<Void> deleteTask(@PathVariable Long id) {
taskService.deleteTask(id);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
@@ -7,7 +7,6 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
@@ -19,9 +18,9 @@ public class HeaderVersionFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(
@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain)
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
response.setHeader("X-BUILD-INFO", appVersionService.getVersion());
filterChain.doFilter(request, response);
@@ -9,7 +9,6 @@ import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -28,9 +27,9 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(
@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain)
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
@@ -4,14 +4,12 @@ import jakarta.servlet.http.HttpServletRequest;
import org.springframework.aot.hint.ProxyHints;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
/** This class creates a RuntimeHint for the ServletRequest class. */
public class HttpServletRequestRuntimeHint implements RuntimeHintsRegistrar {
@Override
public void registerHints(@NonNull RuntimeHints hints, @Nullable ClassLoader classLoader) {
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
try {
ProxyHints proxies = hints.proxies();
proxies.registerJdkProxy(HttpServletRequest.class);
@@ -7,8 +7,6 @@ import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
/**
* This class creates RuntimeHints for JJWT exceptions to ensure they are available at runtime in
@@ -20,7 +18,7 @@ public class JjwtRuntimeHints {
static class JjwtHintsRegistrar implements RuntimeHintsRegistrar {
@Override
public void registerHints(@NonNull RuntimeHints hints, @Nullable ClassLoader classLoader) {
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
// Register JJWT exceptions for reflection
hints
.reflection()
@@ -6,7 +6,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.info.BuildProperties;
import org.springframework.context.event.EventListener;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
/** Service to retrieve application version information. */
@@ -22,7 +21,7 @@ public class AppVersionService {
*
* @param buildProperties the build properties injected by Spring Boot
*/
public AppVersionService(@Autowired(required = false) @Nullable BuildProperties buildProperties) {
public AppVersionService(@Autowired(required = false) BuildProperties buildProperties) {
this.buildProperties = buildProperties;
}
@@ -13,7 +13,7 @@ import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@@ -18,7 +18,6 @@ import java.util.Objects;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;
/** This class implements the NoteService interface methods. */
@@ -76,7 +75,7 @@ public class NoteService {
* @param noteId The task id in the database.
* @return {@link NoteResponse} with the found task or throw a {@link TaskNotFoundException}.
*/
public NoteResponse getNoteById(@NonNull Long noteId) {
public NoteResponse getNoteById(Long noteId) {
UserEntity user = getCurrentUser();
logger.info("Get note " + noteId + " to user " + user.getId());
@@ -127,7 +126,7 @@ public class NoteService {
* @return {@link NoteResponse} containing the updated note.
*/
@Transactional
public NoteResponse patchNote(@NonNull Long noteId, NotePatchRequest patch) {
public NoteResponse patchNote(Long noteId, NotePatchRequest patch) {
UserEntity user = getCurrentUser();
logger.info("Patching task " + noteId + " to user " + user.getId());
@@ -174,7 +173,7 @@ public class NoteService {
* @param noteId The note id from the database.
*/
@Transactional
public void deleteNote(@NonNull Long noteId) {
public void deleteNote(Long noteId) {
UserEntity user = getCurrentUser();
logger.info("Deleting note " + noteId + " to user " + user.getId());
@@ -21,7 +21,6 @@ import java.util.Objects;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;
/** This class contains the implementation for the Task Service class. */
@@ -80,7 +79,7 @@ public class TaskService {
* @param taskId The task id in the database.
* @return {@link TaskResponse} with the found task or throw a {@link TaskNotFoundException}.
*/
public TaskResponse getTaskById(@NonNull Long taskId) {
public TaskResponse getTaskById(Long taskId) {
UserEntity user = getCurrentUser();
logger.info("Get task " + taskId + " to user " + user.getId());
@@ -131,7 +130,7 @@ public class TaskService {
* @return {@link TaskResponse} with the updated content.
*/
@Transactional
public TaskResponse patchTask(@NonNull Long taskId, TaskPatchRequest patch) {
public TaskResponse patchTask(Long taskId, TaskPatchRequest patch) {
UserEntity user = getCurrentUser();
logger.info("Patching task " + taskId + " to user " + user.getId());
@@ -177,7 +176,7 @@ public class TaskService {
* @param taskId The task id in the database
*/
@Transactional
public void deleteTask(@NonNull Long taskId) {
public void deleteTask(Long taskId) {
UserEntity user = getCurrentUser();
logger.info("Deleting task " + taskId + " to user " + user.getId());
@@ -15,15 +15,14 @@ import java.time.LocalDateTime;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
@SpringBootTest
@AutoConfigureMockMvc
@SuppressWarnings("null")
class AuthenticationControllerTest {
@Autowired private MockMvc mockMvc;
@@ -11,8 +11,8 @@ import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -27,7 +27,6 @@ class HomeControllerTest {
@MockitoBean private HomeService homeService;
@Test
@SuppressWarnings("null")
@DisplayName("Get task tags following the happy path it should succeed")
@WithMockUser(username = "user@domain.com", password = "abcde123456A@")
void getTasksTags_happyPath_shouldSucceed() throws Exception {
@@ -46,9 +45,8 @@ class HomeControllerTest {
}
@Test
@SuppressWarnings("null")
@DisplayName("Get task tags not authorized it should fail")
void getTasksTags_notAuthorized_shouldSucceed() throws Exception {
void getTasksTags_notAuthorized_shouldFail() throws Exception {
mockMvc
.perform(
get("/rest/home/tasks/tags")
@@ -23,8 +23,8 @@ import org.hamcrest.Matchers;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -32,7 +32,6 @@ import org.springframework.test.web.servlet.MockMvc;
@SpringBootTest
@AutoConfigureMockMvc
@SuppressWarnings("null")
class NoteControllerTest {
@Autowired private MockMvc mockMvc;
@@ -21,8 +21,8 @@ import org.hamcrest.Matchers;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -30,7 +30,6 @@ import org.springframework.test.web.servlet.MockMvc;
@SpringBootTest
@AutoConfigureMockMvc
@SuppressWarnings("null")
class TaskControllerTest {
@Autowired private MockMvc mockMvc;
@@ -14,8 +14,8 @@ import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -23,7 +23,6 @@ import org.springframework.test.web.servlet.MockMvc;
@SpringBootTest
@AutoConfigureMockMvc
@SuppressWarnings("null")
class UserControllerTest {
@Autowired private MockMvc mockMvc;
@@ -13,8 +13,8 @@ import br.com.tasknoteapp.server.service.UserSessionService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -22,7 +22,6 @@ import org.springframework.test.web.servlet.MockMvc;
@SpringBootTest
@AutoConfigureMockMvc
@SuppressWarnings("null")
class UserSessionControllerTest {
@Autowired private MockMvc mockMvc;
@@ -11,9 +11,9 @@ import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace;
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.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase.Replace;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@@ -9,9 +9,9 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
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.AutoConfigureTestDatabase.Replace;
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.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase.Replace;
import org.springframework.test.context.jdbc.Sql;
@DataJpaTest
@@ -6,9 +6,9 @@ import java.util.UUID;
import org.junit.jupiter.api.Assertions;
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.AutoConfigureTestDatabase.Replace;
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.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase.Replace;
import org.springframework.test.context.jdbc.Sql;
@DataJpaTest
@@ -34,6 +34,7 @@ import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.core.env.Environment;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
@@ -41,10 +42,8 @@ import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@SuppressWarnings("null")
@ExtendWith(SpringExtension.class)
@ExtendWith(MockitoExtension.class)
class AuthServiceTest {
@Mock private UserRepository userRepository;
@@ -95,8 +94,6 @@ class AuthServiceTest {
entity.setEmailUuid(UUID.randomUUID());
when(userRepository.save(any())).thenReturn(entity);
when(jwtService.generateToken(any())).thenReturn("a1b2c3");
doNothing().when(mailgunEmailService).sendNewUser(any());
UserResponseWithToken token = authService.signUpNewUser(request);
@@ -532,8 +529,6 @@ class AuthServiceTest {
existing.setEmail(email);
when(userRepository.findByEmail(email)).thenReturn(Optional.of(existing));
doNothing().when(mailgunEmailService).sendNewUser(existing);
Assertions.assertDoesNotThrow(() -> authService.resendEmailConfirmation(email));
verify(mailgunEmailService, times(0)).sendNewUser(existing);
}
@@ -13,14 +13,13 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
/** Test class generated by Copilot. I had to tweak it, to make it work. */
@SuppressWarnings("null")
@ExtendWith(MockitoExtension.class)
class MailgunEmailServiceTest {
@@ -28,7 +28,6 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@SuppressWarnings("null")
@ExtendWith(MockitoExtension.class)
class NoteServiceTest {
@@ -34,10 +34,9 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.mockito.Mock;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.mockito.junit.jupiter.MockitoExtension;
@SuppressWarnings("null")
@ExtendWith(SpringExtension.class)
@ExtendWith(MockitoExtension.class)
class TaskServiceTest {
@Mock TaskRepository taskRepository;
@@ -535,8 +534,6 @@ class TaskServiceTest {
String searchTerm = null;
when(taskRepository.findAllBySearchTerm(null, USER_ID)).thenReturn(List.of());
List<TaskResponse> responses = taskService.searchTasks(searchTerm);
assertNotNull(responses);
@@ -16,10 +16,9 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.mockito.junit.jupiter.MockitoExtension;
@SuppressWarnings("null")
@ExtendWith(SpringExtension.class)
@ExtendWith(MockitoExtension.class)
class UserSessionServiceTest {
// Test class generated by GitHub Copilot
@@ -26,7 +26,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.test.util.ReflectionTestUtils;
@SuppressWarnings("null")
@ExtendWith(MockitoExtension.class)
class JwtServiceImplTest {