diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index f59d5f75b..000000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,40 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node -{ - "name": "my-nethesis", - // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "build": { - "context": "..", - "dockerfile": "../frontend/Containerfile", - "target": "dev" - }, - "workspaceMount": "source=${localWorkspaceFolder},target=/app,type=bind,Z", - "workspaceFolder": "/app", - "runArgs": ["--userns=keep-id", "--name=my-nethesis-dev"], - "appPort": "5173:5173", - "customizations": { - "vscode": { - "extensions": [ - "Vue.volar", - "dbaeumer.vscode-eslint", - "EditorConfig.EditorConfig", - "esbenp.prettier-vscode", - "streetsidesoftware.code-spell-checker", - "bradlc.vscode-tailwindcss", - "foxundermoon.shell-format", - "vitest.explorer", - "streetsidesoftware.code-spell-checker-italian" - ] - } - } - // Features to add to the dev container. More info: https://containers.dev/features. - // "features": {}, - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "yarn install", - // Configure tool-specific properties. - // "customizations": {}, - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" -} diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index 641907f24..e9ea49be3 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -92,7 +92,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v7 with: - node-version: '20' + node-version-file: .nvmrc cache: 'npm' cache-dependency-path: frontend/package-lock.json diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index db56f673c..e64c8ec24 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v7 with: - node-version: '22' + node-version-file: .nvmrc cache: 'npm' cache-dependency-path: docs/package-lock.json diff --git a/.github/workflows/release-production.yml b/.github/workflows/release-production.yml index 6f00fc59c..79685e9cb 100644 --- a/.github/workflows/release-production.yml +++ b/.github/workflows/release-production.yml @@ -102,7 +102,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v7 with: - node-version: '20' + node-version-file: .nvmrc cache: 'npm' cache-dependency-path: frontend/package-lock.json diff --git a/.gitignore b/.gitignore index 06125de1d..b52d149b4 100644 --- a/.gitignore +++ b/.gitignore @@ -45,8 +45,9 @@ config.yaml proxy/*.pem # IDE -.vscode/ .idea/ +.vscode/* +!.vscode/extensions.json # Logs *.log diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..b7179aed0 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +24.20.0 diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..eb6d14aa2 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,14 @@ +{ + "recommendations": [ + "Vue.volar", + "dbaeumer.vscode-eslint", + "EditorConfig.EditorConfig", + "esbenp.prettier-vscode", + "streetsidesoftware.code-spell-checker", + "streetsidesoftware.code-spell-checker-italian", + "bradlc.vscode-tailwindcss", + "foxundermoon.shell-format", + "vitest.explorer", + "golang.go" + ] +} diff --git a/README.md b/README.md index f17775d27..f50f193b5 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Web application providing centralized authentication and management using Logto ## ๐Ÿš€ Quick Start ### Requirements -- **Development**: Go 1.24+, Node.js 20+ LTS, Make +- **Development**: Go 1.24+, Node.js per `.nvmrc` at the repo root, Make - **Containers**: Docker OR Podman (optional, for full infrastructure) - **External**: Logto instance with M2M app and Management API permissions - **Deploy**: Render account with GitHub integration diff --git a/docs/docs/contributing.md b/docs/docs/contributing.md index 48ec43a1b..4f8a09327 100644 --- a/docs/docs/contributing.md +++ b/docs/docs/contributing.md @@ -103,8 +103,8 @@ Common problems and solutions. ### Prerequisites -- Node.js 20+ -- npm +- Node.js โ€” the version in `.nvmrc` at the repo root (`nvm install && nvm use`). + npm ships with Node, so there is nothing separate to install. ```bash # Install dependencies diff --git a/docs/i18n/it/docusaurus-plugin-content-docs/current/contributing.md b/docs/i18n/it/docusaurus-plugin-content-docs/current/contributing.md index b5b5490c2..8637debd6 100644 --- a/docs/i18n/it/docusaurus-plugin-content-docs/current/contributing.md +++ b/docs/i18n/it/docusaurus-plugin-content-docs/current/contributing.md @@ -46,8 +46,8 @@ docs/ ## Prerequisiti -- **Node.js** 20 o superiore -- **npm** (incluso con Node.js) +- **Node.js** โ€” la versione indicata in `.nvmrc` nella radice del repository + (`nvm install && nvm use`). npm รจ incluso in Node.js, non serve installarlo a parte. ## Sviluppo Locale diff --git a/docs/package-lock.json b/docs/package-lock.json index 7edf2c748..a788cc18e 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -25,7 +25,7 @@ "typescript": "~5.6.2" }, "engines": { - "node": ">=20.0" + "node": ">=24" } }, "node_modules/@11ty/gray-matter": { diff --git a/docs/package.json b/docs/package.json index 7f8c21778..658ba709d 100644 --- a/docs/package.json +++ b/docs/package.json @@ -44,7 +44,7 @@ ] }, "engines": { - "node": ">=20.0" + "node": ">=24" }, "overrides": { "@babel/plugin-transform-modules-systemjs": "^7.29.7", diff --git a/frontend/Containerfile b/frontend/Containerfile index acad11c39..cbcbd5f69 100644 --- a/frontend/Containerfile +++ b/frontend/Containerfile @@ -1,12 +1,9 @@ # Build stage -FROM docker.io/library/node:22.18.0 AS base +# Node version: keep in sync with /.nvmrc +FROM docker.io/library/node:24.20.0 AS base WORKDIR /app -# Development stage -FROM base as dev -CMD ["sh", "-c", "npm install && npm run dev"] - FROM base as builder # Copy build trigger file to force rebuilds when it changes COPY .render-build-trigger /tmp/build-trigger diff --git a/frontend/README.md b/frontend/README.md index e624c38ba..339f8d16b 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -5,9 +5,8 @@ Vue.js web application for My Nethesis with Logto authentication and Role-Based ## Quick Start ### Prerequisites -- Node.js 20+ LTS -- NPM -- Backend API running +- Node.js โ€” the exact version in [`.nvmrc`](../.nvmrc) at the repo root. See [Node version](#node-version). +- Backend API running on port 8080 - Logto instance configured ### Setup @@ -16,13 +15,31 @@ Vue.js web application for My Nethesis with Logto authentication and Role-Based > Start it first with `cd backend && make dev-up && make run`. ```bash -# Install dependencies -npm ci - -# Start development server (port 5173) -npm run dev +nvm install # no argument: reads ../.nvmrc, installs that version and switches to it +node -v # must match ../.nvmrc +npm ci # npm ships inside Node โ€” nothing separate to install +npm run dev # development server on port 5173 ``` +### Node version + +One version is pinned for the whole repo, at the **root** rather than here, because +nvm and fnm both search *upward* from the current directory โ€” so a single pin +covers `frontend/` and `docs/` alike. + +`.nvmrc` is the only version file, because every manager in practical use here +reads it: both nvm and fnm do. + +- **nvm**: `nvm install`, then `nvm use` in every new shell. nvm does **not** switch + automatically; add the `cd` hook from nvm's "Deeper Shell Integration" section to + your shell rc if you want it to. +- **fnm**: `fnm install && fnm use`, or `eval "$(fnm env --use-on-cd)"` to automate it. + +`engines` in `package.json` is the backstop. On the wrong Node, `npm ci` still +succeeds but prints `EBADENGINE` โ€” treat that as an error, because `npm run +type-check` would then check against `@types/node` for a runtime you are not +actually running. + ### Required Environment Variables Environment files must be generated using the `sync` tool. See [sync README](../sync/README.md) for details. @@ -91,47 +108,15 @@ npm run qa npm run preview ``` -### Container Development - -#### Podman Development -```bash -# Start development container -./dev.sh +### Running without installing Node -# Build container image -./dev.sh build - -# Run commands in container -./dev.sh npm run lint-fix -./dev.sh npm run format-fix -./dev.sh bash -``` +There is no container-based dev server: `npm run dev` on the host is the only +development path. -#### VSCode Dev Containers - -**Important Notes:** -- Modifying `dev.containers.dockerPath` setting affects all projects globally -- This procedure may not work on [VSCodium](https://vscodium.com/) - -**Setup:** -1. Install [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) -2. Configure Podman support: - - Go to `File > Preferences > Settings` - - Search for `dev.containers.dockerPath` - - Set the value to `podman` -3. Open the frontend directory in VSCode -4. Open Command Palette (`CTRL+SHIFT+P`) โ†’ "Reopen in Container" (or "Rebuild and Reopen in Container") -5. Open integrated terminal: `View > Terminal` -6. Run development commands: - ```bash - npm install # Install dependencies - npm run dev # Start development server - npm run lint-fix # Fix linting issues - npm run format-fix # Format source files - npm run qa # Start QA environment server - ``` - -Container configuration is in `.devcontainer/devcontainer.json`. +To run the app without installing anything, use the full stack from the repo +root โ€” `docker-compose up -d`, app on http://localhost:9090. It needs a root `.env` +supplying the `VITE_LOGTO_*` values, which compose declares mandatory. That builds the +frontend's `production` target, so it is a build, not a live-reload server. ## Testing @@ -167,8 +152,6 @@ frontend/ โ”‚ โ”œโ”€โ”€ views/ # Page components โ”‚ โ””โ”€โ”€ i18n/ # Internationalization โ”œโ”€โ”€ public/ # Static assets -โ”œโ”€โ”€ .devcontainer/ # VSCode Dev Container config -โ”œโ”€โ”€ dev.sh # Podman development script โ””โ”€โ”€ build.sh # Production build script ``` diff --git a/frontend/dev.sh b/frontend/dev.sh deleted file mode 100755 index f677583be..000000000 --- a/frontend/dev.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env sh - -set -e - -dev_image=${DEV_IMAGE:-"my-nethesis-ui:dev-22.14.0"} -container_name=my-nethesis-ui-dev - -build_image() { - podman build \ - --force-rm \ - --layers \ - --target dev \ - --tag "${dev_image}" \ - . -} - -if ! podman image exists "$dev_image"; then - build_image -fi - -if [ "$#" -gt 0 ]; then - if [ "$1" = "build" ]; then - build_image - else - if podman container exists $container_name; then - podman exec \ - --interactive \ - --tty \ - $container_name "$@" - else - podman run \ - --rm \ - --interactive \ - --tty \ - --volume "$(pwd)":/app:Z \ - "${dev_image}" "$@" - fi - fi -else - podman run \ - --name $container_name \ - --replace \ - --rm \ - --interactive \ - --tty \ - --publish 5173:5173 \ - --volume "$(pwd)":/app:Z \ - "${dev_image}" -fi diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ebefa41c3..6439f78ed 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -37,7 +37,7 @@ "@pinia/colada-devtools": "^1.1.2", "@tsconfig/node22": "^22.0.1", "@types/lodash": "^4.17.18", - "@types/node": "^22.14.0", + "@types/node": "^24.0.0", "@vitejs/plugin-vue": "^5.2.3", "@vitest/coverage-v8": "^3.2.4", "@vue/eslint-config-prettier": "^10.2.0", @@ -56,6 +56,10 @@ "vite-plugin-vue-devtools": "^7.7.2", "vitest": "^3.2.4", "vue-tsc": "^2.2.8" + }, + "engines": { + "node": ">=24", + "npm": ">=11" } }, "node_modules/@ampproject/remapping": { @@ -2694,13 +2698,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.20.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", - "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", + "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", "devOptional": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/web-bluetooth": { @@ -7720,9 +7724,9 @@ } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "devOptional": true, "license": "MIT" }, diff --git a/frontend/package.json b/frontend/package.json index 4e8e77d8c..da9998ef3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,6 +3,10 @@ "version": "0.8.3", "private": true, "type": "module", + "engines": { + "node": ">=24", + "npm": ">=11" + }, "scripts": { "dev": "vite --host", "qa": "vite --host --mode qa", @@ -59,7 +63,7 @@ "@pinia/colada-devtools": "^1.1.2", "@tsconfig/node22": "^22.0.1", "@types/lodash": "^4.17.18", - "@types/node": "^22.14.0", + "@types/node": "^24.0.0", "@vitejs/plugin-vue": "^5.2.3", "@vitest/coverage-v8": "^3.2.4", "@vue/eslint-config-prettier": "^10.2.0", diff --git a/frontend/tsconfig.node.json b/frontend/tsconfig.node.json index a83dfc9d4..8cf0c0a98 100644 --- a/frontend/tsconfig.node.json +++ b/frontend/tsconfig.node.json @@ -1,4 +1,8 @@ { + // Runtime is pinned to Node 24 (/.nvmrc) and @types/node tracks it, but the base + // config stays on node22: @tsconfig/node24 uses lib "ESNext.Error", which needs + // TypeScript >= 5.9, and this repo pins typescript ~5.8.0. Only affects the + // lib/target used to check the build config files below, so the gap is harmless. "extends": "@tsconfig/node22/tsconfig.json", "include": [ "vite.config.*",