Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "10.0.8",
"version": "10.0.11",
"commands": [
"dotnet-ef"
],
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
backend: ${{ steps.filter.outputs.backend }}
frontend: ${{ steps.filter.outputs.frontend }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: dorny/paths-filter@v4
id: filter
with:
Expand All @@ -39,13 +39,13 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- uses: actions/setup-dotnet@v5
- uses: actions/setup-dotnet@v6
with:
global-json-file: global.json

- uses: actions/cache@v5
- uses: actions/cache@v6
with:
path: ~/.nuget/packages
key: nuget-${{ runner.os }}-${{ hashFiles('src/backend/**/*.csproj', 'src/backend/Directory.Packages.props') }}
Expand Down Expand Up @@ -92,15 +92,15 @@ jobs:
run:
working-directory: src/frontend
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- uses: pnpm/action-setup@v6
with:
package_json_file: src/frontend/package.json

- uses: actions/setup-node@v6
- uses: actions/setup-node@v7
with:
node-version: 22
node-version: 24
cache: pnpm
cache-dependency-path: src/frontend/pnpm-lock.yaml

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 1

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 1

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
backend: ${{ steps.filter.outputs.backend }}
frontend: ${{ steps.filter.outputs.frontend }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: dorny/paths-filter@v4
id: filter
with:
Expand All @@ -56,7 +56,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- uses: docker/setup-buildx-action@v4

Expand All @@ -75,7 +75,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7

- uses: docker/setup-buildx-action@v4

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Every project starts the same way: authentication, role management, rate limitin

- [Docker Desktop](https://www.docker.com/products/docker-desktop/)
- [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0)
- [Node.js 22+](https://nodejs.org/) (run `corepack enable` for pnpm)
- [Node.js 24+](https://nodejs.org/) (run `corepack enable` for pnpm)
- [Git](https://git-scm.com/)

### 1. Clone & Initialize
Expand Down
48 changes: 48 additions & 0 deletions docs/sessions/2026-08-17-dependency-updates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Dependency Updates (August 2026)

**Date**: 2026-08-17
**Scope**: Bring all NuGet, npm and GitHub Actions dependencies to their latest versions, superseding the open Dependabot PRs.

## Summary

Updated every backend NuGet package, every frontend npm package and every GitHub Action to the latest release, including several major bumps (SkiaSharp 4, NSubstitute 6, ESLint 10, Vite 8, Vitest 4, TypeScript 6). Node.js runtime moved from 22 to 24 (active LTS). Small code adaptations were needed for Vitest 4 mock semantics and the new ESLint 10 `no-useless-assignment` rule. Backend (1046 tests) and frontend (286 tests, lint, svelte-check, production build, Docker image) are all green.

## Changes Made

| File | Change | Reason |
|------|--------|--------|
| `src/backend/Directory.Packages.props` | All packages to latest; framework 10.0.11 | Security/bug fixes; supersedes Dependabot #519, #520, #521, #522, #503 |
| `.config/dotnet-tools.json` | dotnet-ef 10.0.8 -> 10.0.11 | Keep tool aligned with EF Core version |
| `src/frontend/package.json`, `pnpm-lock.yaml` | All packages to latest; pnpm 10.34.5 | Supersedes Dependabot #515 |
| `src/frontend/vite.config.ts` | Add `clearMocks: true` | Vitest 4: `restoreMocks` no longer resets `vi.fn()` call state |
| `src/frontend/src/lib/utils/crop.test.ts` | `Image` stub uses a regular function | Vitest 4: `vi.fn(arrow)` cannot be invoked with `new` |
| `src/frontend/src/lib/components/ui/sidebar/sidebar-trigger.svelte` | `bind:ref` on `<Button>` | ESLint 10 `no-useless-assignment`; the bindable `ref` was never forwarded |
| `src/frontend/src/lib/components/ui/textarea/textarea.svelte` | Reformatted | Prettier 3.9 output changed |
| `src/frontend/project.inlang/README.md` | Regenerated | Paraglide 2.24 regenerates it on compile |
| `.github/workflows/*.yml` | checkout v7, cache v6, setup-node v7, setup-dotnet v6, Node 24 | Supersedes Dependabot #501, #504, #514 |
| `src/frontend/Dockerfile`, `README.md`, `docs/troubleshooting.md` | Node 22 -> 24 | Node 24 is the active LTS; matches `@types/node` |

## Decisions & Reasoning

### TypeScript 6, not 7

- **Choice**: `typescript@~6.0.3`
- **Alternatives considered**: TypeScript 7.0.2 (native Go port / tsgo)
- **Reasoning**: svelte-check requires TS 6 *and* TS 7 installed side by side plus an experimental `--tsgo` flag. Too experimental for a template; revisit when svelte-check supports TS 7 natively.

### Stay on pnpm 10.x

- **Choice**: pnpm 10.34.5 (latest 10.x)
- **Alternatives considered**: pnpm 11.22
- **Reasoning**: pnpm 11 removes `pnpm.onlyBuiltDependencies` from `package.json` (needs `allowBuilds` in `pnpm-workspace.yaml`), stops reading non-auth settings from `.npmrc`, and enables `minimumReleaseAge`/`strictDepBuilds` by default. That is a config migration, not a version bump, and is better done as its own PR.

### Node.js 24 runtime

- **Choice**: Bump CI, Dockerfile and docs to Node 24
- **Reasoning**: Node 22 is in maintenance; 24 is the active LTS. `@types/node` pinned to `^24` to match the runtime rather than the newest 26.x line.

## Follow-Up Items

- [ ] Migrate to pnpm 11 (`pnpm-workspace.yaml`, `allowBuilds`, `.npmrc` cleanup)
- [ ] TypeScript 7 once svelte-check supports it without the dual install
- [ ] Nine pre-existing `state_referenced_locally` svelte-check warnings (unchanged by this update)
2 changes: 1 addition & 1 deletion docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ docker compose version
| Tool | Required | Check |
|---|---|---|
| .NET SDK | 10.0+ (pinned in `global.json`) | `dotnet --version` |
| Node.js | 22+ | `node --version` |
| Node.js | 24+ | `node --version` |
| pnpm | 10.x (managed via corepack) | `pnpm --version` |
| Docker | Recent with Compose V2 | `docker compose version` |
| Git | Any recent version | `git --version` |
Expand Down
56 changes: 28 additions & 28 deletions src/backend/Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<FrameworkVersion>10.0.8</FrameworkVersion>
<FrameworkVersion>10.0.11</FrameworkVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Aspire.Hosting.JavaScript" Version="13.3.5" />
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="13.3.5" />
<PackageVersion Include="Aspire.Hosting.JavaScript" Version="13.4.6" />
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="13.4.6" />

<PackageVersion Include="AspNetCore.HealthChecks.NpgSql" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Caching.Hybrid" Version="10.6.0" />
<PackageVersion Include="Microsoft.Extensions.Caching.Hybrid" Version="10.9.0" />
<PackageVersion Include="Fluid.Core" Version="2.31.0" />
<PackageVersion Include="MailKit" Version="4.16.0" />
<PackageVersion Include="MailKit" Version="4.17.0" />
<PackageVersion Include="FluentValidation.AspNetCore" Version="11.3.1" />
<PackageVersion Include="JetBrains.Annotations" Version="2025.2.4" />
<PackageVersion Include="JetBrains.Annotations" Version="2026.2.0" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(FrameworkVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="$(FrameworkVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="$(FrameworkVersion)" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="$(FrameworkVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(FrameworkVersion)" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="10.6.0" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="10.9.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(FrameworkVersion)" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="10.6.0" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.15.3" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.2" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="10.9.0" />
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.3" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.17.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.17.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.17.0" />
<!-- EF Core OTEL instrumentation is stable in practice but officially pre-release. Widely used; tracks the main OTEL package release cycle. -->
<PackageVersion Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.12.0-beta.2" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.15.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.15.1" />
<PackageVersion Include="Scalar.AspNetCore" Version="2.14.14" />
<PackageVersion Include="Serilog" Version="4.3.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.17.0-beta.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.17.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.17.0" />
<PackageVersion Include="Scalar.AspNetCore" Version="2.16.20" />
<PackageVersion Include="Serilog" Version="4.4.0" />
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageVersion Include="Serilog.Sinks.Async" Version="2.1.0" />
<!-- Hangfire transitively depends on an older Newtonsoft.Json with CVE-2024-21907. Pinning to 13.0.4 forces the patched version. Not used directly - our code uses System.Text.Json only. -->
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="Hangfire.AspNetCore" Version="1.8.23" />
<PackageVersion Include="Hangfire.Core" Version="1.8.23" />
<PackageVersion Include="Hangfire.AspNetCore" Version="1.8.24" />
<PackageVersion Include="Hangfire.Core" Version="1.8.24" />
<PackageVersion Include="Hangfire.PostgreSql" Version="1.21.1" />
<PackageVersion Include="CommunityToolkit.Aspire.Hosting.MailPit" Version="13.3.0" />
<PackageVersion Include="CommunityToolkit.Aspire.Hosting.Minio" Version="13.3.0" />
<PackageVersion Include="AWSSDK.S3" Version="4.0.23.4" />
<PackageVersion Include="SkiaSharp" Version="3.119.4" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.119.4" />
<PackageVersion Include="CommunityToolkit.Aspire.Hosting.MailPit" Version="13.4.0" />
<PackageVersion Include="CommunityToolkit.Aspire.Hosting.Minio" Version="13.4.0" />
<PackageVersion Include="AWSSDK.S3" Version="4.0.102.1" />
<PackageVersion Include="SkiaSharp" Version="4.151.1" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="4.151.1" />
</ItemGroup>
<ItemGroup Label="Test">
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="4.0.0" />
<PackageVersion Include="NSubstitute" Version="6.2.0" />
<PackageVersion Include="NSubstitute.Analyzers.CSharp" Version="1.0.17" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(FrameworkVersion)" />
<PackageVersion Include="NetArchTest.Rules" Version="1.3.2" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="10.6.0" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="10.9.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="$(FrameworkVersion)" />
<PackageVersion Include="coverlet.collector" Version="10.0.1" />
</ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:22-alpine AS base
FROM node:24-alpine AS base
WORKDIR /app
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
Expand All @@ -14,7 +14,7 @@ COPY . .

RUN pnpm run build

FROM node:22-alpine
FROM node:24-alpine
WORKDIR /app
COPY --from=prod-deps /app/node_modules node_modules/
COPY --from=builder /app/build build/
Expand Down
60 changes: 30 additions & 30 deletions src/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"private": true,
"version": "0.0.1",
"type": "module",
"packageManager": "pnpm@10.29.3",
"packageManager": "pnpm@10.34.5",
"scripts": {
"dev": "vite dev",
"build": "vite build",
Expand All @@ -18,51 +18,51 @@
"api:generate": "openapi-typescript http://localhost:{INIT_API_PORT}/openapi/v1.json -o ./src/lib/api/v1.d.ts && prettier --write ./src/lib/api/v1.d.ts"
},
"devDependencies": {
"@eslint/compat": "^1.4.0",
"@eslint/js": "^9.39.1",
"@inlang/paraglide-js": "^2.15.1",
"@lucide/svelte": "^0.577.0",
"@sveltejs/adapter-node": "^5.5.4",
"@sveltejs/kit": "^2.55.0",
"@sveltejs/vite-plugin-svelte": "^6.2.4",
"@tailwindcss/vite": "^4.2.2",
"@types/node": "^22",
"eslint": "^9.39.1",
"@eslint/compat": "^2.1.0",
"@eslint/js": "^10.0.1",
"@inlang/paraglide-js": "^2.24.1",
"@lucide/svelte": "^1.31.0",
"@sveltejs/adapter-node": "^5.5.7",
"@sveltejs/kit": "^2.70.2",
"@sveltejs/vite-plugin-svelte": "^7.3.0",
"@tailwindcss/vite": "^4.3.3",
"@types/node": "^24.13.3",
"eslint": "^10.8.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-svelte": "^3.16.0",
"eslint-plugin-svelte": "^3.23.0",
"formsnap": "^2.0.1",
"globals": "^17.4.0",
"globals": "^17.11.0",
"openapi-typescript": "^7.13.0",
"prettier": "^3.8.1",
"prettier-plugin-svelte": "^3.5.1",
"prettier-plugin-tailwindcss": "^0.7.2",
"svelte": "^5.55.0",
"svelte-check": "^4.4.5",
"sveltekit-superforms": "^2.30.0",
"tailwindcss": "^4.2.2",
"prettier": "^3.9.6",
"prettier-plugin-svelte": "^4.1.1",
"prettier-plugin-tailwindcss": "^0.8.1",
"svelte": "^5.56.9",
"svelte-check": "^4.7.6",
"sveltekit-superforms": "^2.30.2",
"tailwindcss": "^4.3.3",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.9.3",
"typescript-eslint": "^8.57.2",
"vite": "^7.3.1",
"vitest": "^3.2.1",
"zod": "4.3.6"
"typescript": "^6.0.3",
"typescript-eslint": "^8.67.0",
"vite": "^8.2.1",
"vitest": "^4.1.10",
"zod": "4.4.3"
},
"pnpm": {
"onlyBuiltDependencies": [
"esbuild"
]
},
"dependencies": {
"@internationalized/date": "^3.12.0",
"@internationalized/date": "^3.12.3",
"@types/qrcode": "^1.5.6",
"bits-ui": "^2.16.3",
"bits-ui": "^2.18.1",
"clsx": "^2.1.1",
"flag-icons": "^7.5.0",
"openapi-fetch": "^0.17.0",
"qrcode": "^1.5.4",
"svelte-easy-crop": "^5.0.1",
"svelte-sonner": "^1.1.0",
"tailwind-merge": "^3.5.0",
"tailwind-variants": "^3.2.2"
"svelte-sonner": "^1.2.1",
"tailwind-merge": "^3.6.0",
"tailwind-variants": "^3.3.1"
}
}
Loading
Loading