Skip to content

fix: bump client, backend and root dependencies to current majors on Node 24 - #2238

Open
trillium wants to merge 13 commits into
developmentfrom
chore/vrms-deps-bump
Open

trillium wants to merge 13 commits into
developmentfrom
chore/vrms-deps-bump

Conversation

@trillium

Copy link
Copy Markdown
Member

Intent

make one big deps bump please and make sure that the service builds into our dockerized coder worksapce

Context: project is hackforla/VRMS (PRs target development; the captain is an admin there). It is a yarn repo with a root package.json plus client/ and backend/ packages (each with its own yarn.lock), Dockerfiles per tier (client/Dockerfile.{dev,prod,client}, backend/Dockerfile.{api,dev,prod}) and a root docker-compose.yml. The client declares engines.node: "<=18.0.0". Recent work on development already moved Docker builds to Node 24 and the repo root as build context (#2216, #2219). The captain's dockerized Coder workspaces run on a Coder server at http://lnx.hippo-tilapia.ts.net:7080 using the Docker template (base image codercom/enterprise-base:ubuntu).

What Changed

  • Dependencies: Bumped dependencies to current major versions across the root, client/ and backend/ packages, and regenerated all three yarn.lock files.
    • Client: React 19, MUI 9 and @mui/x-date-pickers 9, react-router-dom 7, d3 7, Vite 8 and Vitest 5. The unused @vitejs/plugin-react and @babel/plugin-transform-react-jsx-self were removed.
    • Backend: Express 5, Mongoose 9, @slack/bolt 5, googleapis 185, Helmet 8, jsonwebtoken 9, dotenv/dotenv-expand, node-cron 4, nodemailer 10 and others.
    • Root tooling: Biome 2, Cypress 16, concurrently 10 and others. The old Cypress config files (cypress.json and cypress/plugins/index.js) were replaced with cypress.config.mjs, and biome.json was updated to the v2 schema.
  • Client code changes for the new APIs: The client now mounts with createRoot and uses Routes/element/Navigate in place of Switch/component/Redirect. Components were updated for MUI 9 (Grid, icon names, slotProps, system props, and DatePicker field styles), and the API services no longer build double-slash URLs (baseUrl + '/x') that Express 5 rejects.
  • Backend code changes for Express 5: The backend sets the extended query parser so bracket-style queries like date[$gt] keep working, and the catch-all 404 route is now /{*splat}. A new integration test covers the date[$gt] events query.
  • Node 24 everywhere: client/Dockerfile.dev, client/Dockerfile.prod, backend/Dockerfile.dev and the frontend deploy workflow now use Node 24. The client's engines.node is now >=24, and the stale Node 16 troubleshooting tip was removed from CONTRIBUTING.md.

🤖 Generated with Claude Code

Risk Assessment

🚨 High: This one PR bumps many runtime majors across both tiers (Express 5, Mongoose 9, React 19, MUI 9, react-router 7, d3 7, node-fetch 3, node-cron 4), and it already contains one confirmed silent regression: Express 5's simple query parser makes the event list on the project management page come back empty. It needs human approval and real runtime checks, not just a build.

Testing

All scenarios passed live. I built the backend and client images from the repo's docker-compose.yml on Node 24, along with the client and API production targets, then brought up the dev stack (backend, client and a throwaway mongo) under docker compose. Against that stack I checked the API with curl and the UI with Playwright, taking screenshots. The backend is on Express 5 and mongoose 9. A date[$gt] query returns only future events, so the extended query parser is back. Unknown paths return 404 through the new /{*splat} route, and the header guard still returns 401. The client is on React 19, react-router 7 and MUI 9. Home, login, new and returning pages render, and an unknown route redirects to /. On the new-user check-in form, the MUI 9 Month/Year DatePicker keeps its old look (red rgb(250,17,79), weight 600, 40px tall), and choosing March 2023 works and enables CHECK IN. The new date[$gt] integration test passes inside the built container. I had to fix three setup problems along the way: the Docker daemon is remote, so bind mounts were empty and I baked the source into the images instead; the client hardcodes a request header that has to be quoted in .env; and mongodb-memory-server has no aarch64 debian12 binary, so I pointed it at the ubuntu-22.04 one. Everything was torn down afterwards: containers, volumes, images, the ssh tunnel and the temporary .env files.

  • Live validation: ✅ go - 7 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Developer runs docker compose build from the repo root and the backend and client dev images build on Node 24 with the bumped lockfiles ✅ pass live compose-build.log (both images Built, exit 0); installed-versions.txt
Production image targets (client-production via Dockerfile.client and Dockerfile.prod, api-production) build, including the vite 8 production build ✅ pass live client-prod-build.log ('built in 5.80s'), client-dockerfile-prod-build.log, api-prod-build.log (all exit 0)
Backend boots in compose on Express 5 / mongoose 9 / dotenv-expand 13, connects to Mongo and answers the healthcheck ✅ pass live api-transcript.txt (healthcheck 'I'm Alive!'); container log 'Mongoose connected ... listening on 4000'
Project-management events query with date[$gt] still filters under Express 5 (extended query parser restored) ✅ pass live api-transcript.txt: date[$gt]=2025 returns only future events, date[$lt] returns only Past Event; event-integration-test.txt passes
Adversarial: unknown API and deep paths hit the Express 5 /{*splat} 404 fallback, and requests without the custom header are still rejected ✅ pass live api-transcript.txt: /api/does-not-exist -> 404, /some/deep/unknown/path -> 404, no header -> 401
Client dev server (vite 8, React 19 createRoot, react-router 7) renders home, login, /new and /returning with live events, and an unknown route redirects to / ✅ pass live home.png, login.png, new.png, returning.png, unknown-route.png; Playwright log shows the unknown route ends at '/'
New-user check-in Month/Year DatePicker on MUI x-date-pickers 9 keeps its custom look and lets the user pick a date that enables CHECK IN ✅ pass live checkin-newuser-datepicker-{empty,open,selected}.png; computed style color rgb(250, 17, 79), fontWeight 600, height 40px; value 'March 2023'; CHECK IN enabled
Evidence: docker compose build log (backend + client, Node 24)
time="2026-10-12T19:31:32-07:00" level=warning msg="~/.no-mistakes/worktrees/3cda5f453c2a/01M4SH8X5ZGVJ4KZE599604F8S/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion"
 Image nmvrmstest-client Building 
 Image nmvrmstest-backend Building 
#1 [internal] load local bake definitions
#1 reading from stdin 1.23kB done
#1 DONE 0.0s

#2 [backend internal] load build definition from Dockerfile.api
#2 DONE 0.0s

#3 [client internal] load build definition from Dockerfile.client
#3 transferring dockerfile:
#3 transferring dockerfile: 762B 0.0s done
#3 DONE 0.2s

#2 [backend internal] load build definition from Dockerfile.api
#2 transferring dockerfile: 682B 0.0s done
#2 DONE 0.3s

#4 [backend internal] load metadata for docker.io/library/node:24
#4 DONE 0.9s

#5 [client internal] load metadata for docker.io/library/node:24-alpine
#5 DONE 0.9s

#6 [backend internal] load .dockerignore
#6 transferring context: 335B 0.0s done
#6 DONE 0.1s

#7 [client internal] load build context
#7 transferring context: 1.96kB 0.0s done
#7 DONE 0.1s

#8 [backend internal] load build context
#8 transferring context: 520.64kB 0.1s done
#8 DONE 0.1s

#9 [backend api-development 1/8] FROM docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0
#9 resolve docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0 0.0s done
#9 DONE 0.0s

#10 [client client-development 1/6] FROM docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1
#10 resolve docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1 0.0s done
#10 sha256:e2f4a003057d235ec28208b606f2f9524400c06882b1ffa1c89ceda8213f5fb4 444B / 444B 0.1s done
#10 sha256:d4a23e25aa718dc5c16fb5935f8683eff024fd67902ef1a4929a42da78d4e9d6 1.26MB / 1.26MB 0.1s done
#10 sha256:a9986cd6f37dbddae7862a6d4be71683472e7c2ea708e87db14f8a6393c00f00 0B / 4.19MB 0.2s
#10 sha256:a9986cd6f37dbddae7862a6d4be71683472e7c2ea708e87db14f8a6393c00f00 4.19MB / 4.19MB 0.2s done
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 0B / 56.60MB 0.2s
#10 extracting sha256:a9986cd6f37dbddae7862a6d4be71683472e7c2ea708e87db14f8a6393c00f00
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 7.23MB / 56.60MB 0.3s
#10 extracting sha256:a9986cd6f37dbddae7862a6d4be71683472e7c2ea708e87db14f8a6393c00f00 0.2s done
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 11.53MB / 56.60MB 0.5s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 16.78MB / 56.60MB 0.6s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 20.97MB / 56.60MB 0.8s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 24.12MB / 56.60MB 0.9s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 28.31MB / 56.60MB 1.1s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 32.51MB / 56.60MB 1.4s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 36.70MB / 56.60MB 1.8s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 39.85MB / 56.60MB 2.4s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 42.99MB / 56.60MB 4.1s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 46.14MB / 56.60MB 5.4s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 49.28MB / 56.60MB 5.9s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 56.37MB / 56.60MB 6.2s
#10 sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 56.60MB / 56.60MB 6.2s done
#10 extracting sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c
#10 ...

#9 [backend api-development 1/8] FROM docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0
#9 sha256:064051a853d25d51393f92a2a2e875a57a4345de2a4ba0b3f2168ec53ef70684 448B / 448B 0.1s done
#9 sha256:0a24d4095d0bc6bcbf2f6aff2ef1a74def9a5b307a88387e09428f9ef0189f2c 1.25MB / 1.25MB 0.2s done
#9 sha256:58509fb435f78d52821e0982338ba519f4476e4a6aca2bffaf822bab5825d4b1 3.32kB / 3.32kB 0.1s done
#9 sha256:07dd704887cea4263aa1e8b689966786fa24e65744755227b3d8037984a761fa 59.81MB / 59.81MB 6.2s done
#9 sha256:4562cb873c99b9446ba4daee7180b2d40bbac13aefcf459f2e516776c1ed0458 203.25MB / 203.25MB 5.8s done
#9 sha256:99713dbe79ee22ead7509cd8c7c37d309206e5ddd834ba41611459b49e6ddc06 66.77MB / 66.77MB 3.2s done
#9 sha256:bdc7363672c63abfefdedaf5e03be8e39cb662841d4f31237c4b7d7e3729f65c 23.44MB / 23.44MB 0.7s done
#9 sha256:2a02c40189e361a19e7cb07374fe9925f5c4f7db254ae2b9196348c27c286b03 48.40MB / 48.40MB 1.0s done
#9 extracting sha256:2a02c40189e361a19e7cb07374fe9925f5c4f7db254ae2b9196348c27c286b03
#9 extracting sha256:2a02c40189e361a19e7cb07374fe9925f5c4f7db254ae2b9196348c27c286b03 2.4s done
#9 DONE 7.6s

#10 [client client-development 1/6] FROM docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1
#10 ...

#9 [backend api-development 1/8] FROM docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0
#9 extracting sha256:bdc7363672c63abfefdedaf5e03be8e39cb662841d4f31237c4b7d7e3729f65c
#9 ...

#10 [client client-development 1/6] FROM docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1
#10 extracting sha256:6680b19ad074d7cbe6bf0eb4013d64483980d5cc93bf6774d7effd8bb196df0c 1.8s done
#10 DONE 8.1s

#10 [client client-development 1/6] FROM docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1
#10 extracting sha256:d4a23e25aa718dc5c16fb5935f8683eff024fd67902ef1a4929a42da78d4e9d6 0.1s done
#10 extracting sha256:e2f4a003057d235ec28208b606f2f9524400c06882b1ffa1c89ceda8213f5fb4 0.0s done
#10 DONE 8.2s

#9 [backend api-development 1/8] FROM docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0
#9 extracting sha256:bdc7363672c63abfefdedaf5e03be8e39cb662841d4f31237c4b7d7e3729f65c 0.6s done
#9 DONE 8.2s

#11 [client client-development 2/6] RUN mkdir /srv/client
#11 DONE 0.6s

#9 [backend api-development 1/8] FROM docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0
#9 extracting sha256:99713dbe79ee22ead7509cd8c7c37d309206e5ddd834ba41611459b49e6ddc06
#9 ...

#12 [client client-development 3/6] WORKDIR /srv/client
#12 DONE 0.1s

#13 [client client-development 4/6] RUN mkdir -p node_modules
#13 DONE 0.2s

#9 [backend api-development 1/8] FROM docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0
#9 ...

#14 [client client-development 5/6] COPY client/package*.json ./
#14 DONE 0.0s

#15 [client client-development 6/6] RUN npm install --silent
#15 ...

#9 [backend api-development 1/8] FROM docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0
#9 extracting sha256:99713dbe79ee22ead7509cd8c7c37d309206e5ddd834ba41611459b49e6ddc06 2.0s done
#9 DONE 10.2s

#9 [backend api-development 1/8] FROM docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0
#9 extracting sha256:4562cb873c99b9446ba4daee7180b2d40bbac13aefcf459f2e516776c1ed0458
#9 extracting sha256:4562cb873c99b9446ba4daee7180b2d40bbac13aefcf459f2e516776c1ed0458 3.5s done
#9 DONE 13.7s

#15 [client client-development 6/6] RUN npm install --silent
#15 ...

#9 [backend api-development 1/8] FROM docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0
#9 extracting sha256:58509fb435f78d52821e0982338ba519f4476e4a6aca2bffaf822bab5825d4b1 0.0s done
#9 extracting sha256:07dd704887cea4263aa1e8b689966786fa24e65744755227b3d8037984a761fa
#9 extracting sha256:07dd704887cea4263aa1e8b689966786fa24e65744755227b3d8037984a761fa 1.8s done
#9 DONE 15.4s

#15 [client client-development 6/6] RUN npm install --silent
#15 ...

#9 [backend api-development 1/8] FROM docker.io/library/node:24@sha256:3d27e5c11e5786e309ec3e03f93ae536eb36e6e5eb3714d5eb3300a36157add0
#9 extracting sha256:0a24d4095d0bc6bcbf2f6aff2ef1a74def9a5b307a88387e09428f9ef0189f2c 0.0s done
#9 extracting sha256:064051a853d25d51393f92a2a2e875a57a4345de2a4ba0b3f2168ec53ef70684 done
#9 DONE 15.5s

#16 [backend api-development 2/8] RUN mkdir /srv/backend
#16 DONE 0.7s

#15 [client client-development 6/6] RUN npm install --silent
#15 ...

#17 [backend api-development 3/8] WORKDIR /srv/backend
#17 DONE 0.0s

#18 [backend api-development 4/8] RUN mkdir -p node_modules
#18 DONE 0.2s

#15 [client client-development 6/6] RUN npm install --silent
#15 ...

#19 [backend api-development 5/8] COPY backend/package.json backend/yarn.lock ./
#19 DONE 0.0s

#20 [backend api-development 6/8] RUN yarn install --pure-lockfile
#20 0.280 yarn install v1.22.22
#20 0.314 [1/4] Resolving packages...
#20 0.430 (node:6) [DEP0169] DeprecationWarning: `url.parse()` behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for `url.parse()` vulnerabilities.
#20 0.430 (Use `node --trace-deprecation ...` to show where the warning was created)
#20 0.431 [2/4] Fetching packages...
#20 11.46 warning bare-fs@4.8.4: The engine "bare" appears to be invalid.
#20 11.46 warning bare-os@3.9.1: The engine "bare" appears to be invalid.
#20 11.46 [3/4] Linking dependencies...
#20 11.46 warning " > @slack/bolt@5.1.0" has unmet peer dependency "@types/express@^5.0.0".
#20 11.46 warning "@slack/bolt > @slack/socket-mode@3.1.0" has unmet peer dependency "undici@^7.0.0 || ^8.0.0".
#20 15.05 [4/4] Building fresh packages...
#20 16.68 Done in 16.41s.
#20 DONE 17.2s

#15 [client client-development 6/6] RUN npm install --silent
#15 ...

#21 [backend api-development 7/8] COPY backend/. .
#21 DONE 0.2s

#15 [client client-development 6/6] RUN npm install --silent
#15 ...

#22 [backend api-development 8/8] COPY shared/ /srv/shared/
#22 DONE 0.0s

#23 [backend] exporting to image
#23 exporting layers
#23 exporting layers 40.9s done
#23 exporting manifest sha256:79df96ff78fd8e238e06f615a886587f25a1a498408003f4fd88f4116aa15677 0.0s done
#23 exporting config sha256:b635bc9c949295ca3ed451ce86158239c3b72a0e70b041a7c27c16ff1ab58555 0.0s done
#23 exporting attestation manifest sha256:0f65d5203208f4a3fc6b8e708a1a52e6346bd9d04851d1b9d7ba05256bdf0fb0 0.0s done
#23 exporting manifest list sha256:97aecd4ae48a4577595e2da2a2c288573b0ceeb15abd45e738adc3ebf1f970d2 0.0s done
#23 naming to docker.io/library/nmvrmstest-backend:latest done
#23 unpacking to docker.io/library/nmvrmstest-backend:latest
#23 ...

#15 [client client-development 6/6] RUN npm install --silent
#15 DONE 72.0s

#24 [client] exporting to image
#24 exporting layers
#24 ...

#23 [backend] exporting to image
#23 unpacking to docker.io/library/nmvrmstest-backend:latest 15.8s done
#23 DONE 56.9s

#25 [backend] resolving provenance for metadata file
#25 DONE 0.1s

#24 [client] exporting to image
#24 exporting layers 44.9s done
#24 exporting manifest sha256:5659dc453059fc2247ece1c867d26d99f98cda5b8409b0db80acad0a0e18c8ec
#24 exporting manifest sha256:5659dc453059fc2247ece1c867d26d99f98cda5b8409b0db80acad0a0e18c8ec done
#24 exporting config sha256:6e4b9f755f96ea8951dfbc6f7005c4ea4d71251bef392a21b104aeaeb0f8d088 done
#24 exporting attestation manifest sha256:56213e750cac05b9ee31225805eafc582d2dd8d61c10473f70a777aed12673fa done
#24 exporting manifest list sha256:28ca159a0c2622a61cad6390ad4aedbaf1cc035247b1e6c2f3557baad1da707e done
#24 naming to docker.io/library/nmvrmstest-client:latest done
#24 unpacking to docker.io/library/nmvrmstest-client:latest
#24 unpacking to docker.io/library/nmvrmstest-client:latest 13.0s done
#24 DONE 58.0s

#26 [client] resolving provenance for metadata file
#26 DONE 0.0s
 Image nmvrmstest-client Built 
 Image nmvrmstest-backend Built 
Evidence: Client production image build (vite 8 build)
#0 building with "mini2" instance using docker driver

#1 [internal] load build definition from Dockerfile.client
#1 transferring dockerfile:
#1 transferring dockerfile: 762B 0.0s done
#1 DONE 0.6s

#2 [internal] load metadata for docker.io/library/nginx:latest
#2 ...

#3 [internal] load metadata for docker.io/library/node:24-alpine
#3 DONE 0.3s

#2 [internal] load metadata for docker.io/library/nginx:latest
#2 DONE 1.0s

#4 [internal] load .dockerignore
#4 transferring context: 335B 0.0s done
#4 DONE 0.1s

#5 [client-development 1/6] FROM docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1
#5 resolve docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1 done
#5 CACHED

#6 [client-production 1/3] FROM docker.io/library/nginx:latest@sha256:f9ea18bfa4fad859e1ed38259d711da7ccad2c3516e875cec3351a57c859f571
#6 resolve docker.io/library/nginx:latest@sha256:f9ea18bfa4fad859e1ed38259d711da7ccad2c3516e875cec3351a57c859f571 0.0s done
#6 sha256:b496ef725cba787e61a6f2b964f763fac7eb6930c6730e7f78790db9ca0356d4 1.40kB / 1.40kB 0.1s done
#6 ...

#7 [internal] load build context
#7 transferring context: 2.29MB 0.4s done
#7 DONE 0.4s

#8 [client-development 2/6] RUN mkdir /srv/client
#8 CACHED

#9 [client-development 3/6] WORKDIR /srv/client
#9 CACHED

#10 [client-development 4/6] RUN mkdir -p node_modules
#10 CACHED

#11 [client-development 5/6] COPY client/package*.json ./
#11 CACHED

#12 [client-development 6/6] RUN npm install --silent
#12 CACHED

#6 [client-production 1/3] FROM docker.io/library/nginx:latest@sha256:f9ea18bfa4fad859e1ed38259d711da7ccad2c3516e875cec3351a57c859f571
#6 sha256:74db6078a267237a135673d3411d5a1b28737ba0ce5630fec63d5159054fe73c 1.21kB / 1.21kB 0.2s done
#6 sha256:95266651b1b541574d83631cf675aa3dc817ade54cb6af37d26c13dc749ff884 0B / 405B 0.2s
#6 sha256:c6d8c112974b549fceda2d1617f4b11bc095b1bba824413f20bc29ec61e6e3fe 0B / 956B 0.2s
#6 sha256:95266651b1b541574d83631cf675aa3dc817ade54cb6af37d26c13dc749ff884 405B / 405B 0.2s done
#6 sha256:c6d8c112974b549fceda2d1617f4b11bc095b1bba824413f20bc29ec61e6e3fe 956B / 956B 0.2s done
#6 sha256:a0eaca4f4a896724fcb490d9097423e57e960670bf37724cbfaabc417054ee2e 0B / 31.94MB 0.2s
#6 sha256:848dbae53a0f1433b02cf9bc8659e49e3276c4ab8b10eb0f554d897dc78c5d46 0B / 629B 0.2s
#6 sha256:a0eaca4f4a896724fcb490d9097423e57e960670bf37724cbfaabc417054ee2e 2.18MB / 31.94MB 0.3s
#6 sha256:848dbae53a0f1433b02cf9bc8659e49e3276c4ab8b10eb0f554d897dc78c5d46 629B / 629B 0.2s done
#6 sha256:bbeda6b4abb749f743f4547ef5a28070a14de8caef211daa5afb78d5b5fa21ba 0B / 30.20MB 0.2s
#6 ...

#13 [client-builder 2/6] WORKDIR /srv/client
#13 DONE 0.9s

#6 [client-production 1/3] FROM docker.io/library/nginx:latest@sha256:f9ea18bfa4fad859e1ed38259d711da7ccad2c3516e875cec3351a57c859f571
#6 sha256:a0eaca4f4a896724fcb490d9097423e57e960670bf37724cbfaabc417054ee2e 5.24MB / 31.94MB 0.5s
#6 sha256:bbeda6b4abb749f743f4547ef5a28070a14de8caef211daa5afb78d5b5fa21ba 2.73MB / 30.20MB 0.3s
#6 sha256:bbeda6b4abb749f743f4547ef5a28070a14de8caef211daa5afb78d5b5fa21ba 9.44MB / 30.20MB 0.5s
#6 sha256:a0eaca4f4a896724fcb490d9097423e57e960670bf37724cbfaabc417054ee2e 13.63MB / 31.94MB 0.6s
#6 sha256:bbeda6b4abb749f743f4547ef5a28070a14de8caef211daa5afb78d5b5fa21ba 19.92MB / 30.20MB 0.6s
#6 sha256:a0eaca4f4a896724fcb490d9097423e57e960670bf37724cbfaabc417054ee2e 23.07MB / 31.94MB 0.8s
#6 sha256:bbeda6b4abb749f743f4547ef5a28070a14de8caef211daa5afb78d5b5fa21ba 26.21MB / 30.20MB 0.8s
#6 sha256:a0eaca4f4a896724fcb490d9097423e57e960670bf37724cbfaabc417054ee2e 31.94MB / 31.94MB 1.0s done
#6 sha256:bbeda6b4abb749f743f4547ef5a28070a14de8caef211daa5afb78d5b5fa21ba 30.20MB / 30.20MB 0.9s done
#6 extracting sha256:bbeda6b4abb749f743f4547ef5a28070a14de8caef211daa5afb78d5b5fa21ba
#6 extracting sha256:bbeda6b4abb749f743f4547ef5a28070a14de8caef211daa5afb78d5b5fa21ba 1.7s done
#6 extracting sha256:a0eaca4f4a896724fcb490d9097423e57e960670bf37724cbfaabc417054ee2e
#6 extracting sha256:a0eaca4f4a896724fcb490d9097423e57e960670bf37724cbfaabc417054ee2e 0.9s done
#6 DONE 4.0s

#6 [client-production 1/3] FROM docker.io/library/nginx:latest@sha256:f9ea18bfa4fad859e1ed38259d711da7ccad2c3516e875cec3351a57c859f571
#6 extracting sha256:848dbae53a0f1433b02cf9bc8659e49e3276c4ab8b10eb0f554d897dc78c5d46 0.0s done
#6 extracting sha256:c6d8c112974b549fceda2d1617f4b11bc095b1bba824413f20bc29ec61e6e3fe 0.0s done
#6 extracting sha256:95266651b1b541574d83631cf675aa3dc817ade54cb6af37d26c13dc749ff884 0.0s done
#6 extracting sha256:74db6078a267237a135673d3411d5a1b28737ba0ce5630fec63d5159054fe73c 0.0s done
#6 extracting sha256:b496ef725cba787e61a6f2b964f763fac7eb6930c6730e7f78790db9ca0356d4 0.0s done
#6 DONE 4.1s

#14 [client-production 2/3] COPY client/nginx/default.conf /etc/nginx/conf.d/default.conf
#14 DONE 0.3s

#15 [client-builder 3/6] COPY --from=client-development /srv/client/node_modules node_modules
#15 DONE 15.0s

#16 [client-builder 4/6] COPY client/. .
#16 DONE 0.6s

#17 [client-builder 5/6] COPY shared/ /srv/shared/
#17 DONE 0.0s

#18 [client-builder 6/6] RUN npm run build
#18 1.464 
#18 1.464 > vrms-client@0.3.0 build
#18 1.464 > vite build
#18 1.464 
#18 2.318 vite v8.3.4 building client environment for production...
#18 2.348 transforming...
#18 7.138 ✓ 2097 modules transformed.
#18 7.718 rendering chunks...
#18 8.058 computing gzip size...
#18 8.079 build/index.html                                              2.04 kB │ gzip:   0.94 kB
#18 8.079 build/assets/hflalogo-DAcrAwfK.svg                            6.30 kB │ gzip:   4.74 kB
#18 8.079 build/assets/aliseo-noncommercial-webfont-CvedmeaU.woff2     10.56 kB
#18 8.079 build/assets/aliseo-noncommercial-webfont-D44uqgp9.woff      13.64 kB
#18 8.079 build/assets/22-gaIIUNhE.gif                                 24.19 kB
#18 8.079 build/assets/index-BlxpJTLx.css                              54.85 kB │ gzip:   9.75 kB
#18 8.079 build/assets/index-CMBD5rSU.js                            1,495.50 kB │ gzip: 457.54 kB
#18 8.079 
#18 8.094 [plugin builtin:vite-reporter] 
#18 8.094 (!) Some chunks are larger than 500 kB after minification. Consider:
#18 8.094 - Using dynamic import() to code-split the application
#18 8.094 - Use build.rolldownOptions.output.codeSplitting to improve chunking: https://rolldown.rs/reference/OutputOptions.codeSplitting
#18 8.094 - Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
#18 8.095 �[33m[COMMONJS_VARIABLE_IN_ESM] �[0mThe CommonJS `module` variable is treated as a global variable in an ECMAScript module and may not work as expected
#18 8.095     �[38;5;246m╭�[0m�[38;5;246m─�[0m�[38;5;246m[�[0m ../shared/roles.js:22:3 �[38;5;246m]�[0m
#18 8.095     �[38;5;246m│�[0m
#18 8.095  �[38;5;246m22 │�[0m �[38;5;249m �[0m�[38;5;249m �[0mmodule�[38;5;249m.�[0m�[38;5;249me�[0m�[38;5;249mx�[0m�[38;5;249mp�[0m�[38;5;249mo�[0m�[38;5;249mr�[0m�[38;5;249mt�[0m�[38;5;249ms�[0m�[38;5;249m �[0m�[38;5;249m=�[0m�[38;5;249m �[0m�[38;5;249m{�[0m
#18 8.095  �[38;5;240m   │�[0m   ───┬──  
#18 8.095  �[38;5;240m   │�[0m      ╰──── 
#18 8.095  �[38;5;240m   │�[0m 
#18 8.095  �[38;5;246m29 │�[0m export�[38;5;249m �[0m�[38;5;249m{�[0m�[38;5;249m �[0m�[38;5;249mR�[0m�[38;5;249mO�[0m�[38;5;249mL�[0m�[38;5;249mE�[0m�[38;5;249mS�[0m�[38;5;249m,�[0m�[38;5;249m �[0m�[38;5;249mR�[0m�[38;5;249mO�[0m�[38;5;249mL�[0m�[38;5;249mE�[0m�[38;5;249m_�[0m�[38;5;249mH�[0m�[38;5;249mI�[0m�[38;5;249mE�[0m�[38;5;249mR�[0m�[38;5;249mA�[0m�[38;5;249mR�[0m�[38;5;249mC�[0m�[38;5;249mH�[0m�[38;5;249mY�[0m�[38;5;249m �[0m�[38;5;249m}�[0m�[38;5;249m;�[0m
#18 8.095  �[38;5;240m   │�[0m ───┬──  
#18 8.095  �[38;5;240m   │�[0m    ╰──── This file is considered to be an ECMAScript module because of the `export` keyword here:
#18 8.095 �[38;5;246m────╯�[0m
#18 8.095 
#18 8.095 �[33m[COMMONJS_VARIABLE_IN_ESM] �[0mThe CommonJS `module` variable is treated as a global variable in an ECMAScript module and may not work as expected
#18 8.095     �[38;5;246m╭�[0m�[38;5;246m─�[0m�[38;5;246m[�[0m ../shared/authorizationUtils.js:36:3 �[38;5;246m]�[0m
#18 8.095     �[38;5;246m│�[0m
#18 8.095  �[38;5;246m36 │�[0m �[38;5;249m �[0m�[38;5;249m �[0mmodule�[38;5;249m.�[0m�[38;5;249me�[0m�[38;5;249mx�[0m�[38;5;249mp�[0m�[38;5;249mo�[0m�[38;5;249mr�[0m�[38;5;249mt�[0m�[38;5;249ms�[0m�[38;5;249m �[0m�[38;5;249m=�[0m�[38;5;249m �[0m�[38;5;249m{�[0m
#18 8.095  �[38;5;240m   │�[0m   ───┬──  
#18 8.095  �[38;5;240m   │�[0m      ╰──── 
#18 8.095  �[38;5;240m   │�[0m 
#18 8.095  �[38;5;246m47 │�[0m export�[38;5;249m �[0m�[38;5;249m{�[0m
#18 8.095  �[38;5;240m   │�[0m ───┬──  
#18 8.095  �[38;5;240m   │�[0m    ╰──── This file is considered to be an ECMAScript module because of the `export` keyword here:
#18 8.095 �[38;5;246m────╯�[0m
#18 8.095 
#18 8.117 ✓ built in 5.80s
#18 8.262 npm notice
#18 8.262 npm notice New major version of npm available! 11.19.0 -> 12.2.0
#18 8.262 npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
#18 8.262 npm notice To update run: npm install -g npm@12.2.0
#18 8.262 npm notice
#18 DONE 8.9s

#19 [client-production 3/3] COPY --from=client-builder /srv/client/build /usr/share/nginx/html/
#19 DONE 0.8s

#20 exporting to image
#20 exporting layers
#20 exporting layers 0.2s done
#20 exporting manifest sha256:21a9e453a65331ce4e62cf778aa65ff506f61674392d7d99fa214030d800aeda
#20 exporting manifest sha256:21a9e453a65331ce4e62cf778aa65ff506f61674392d7d99fa214030d800aeda 0.0s done
#20 exporting config sha256:e3830e7af0345a8f243174a8e8dcf6c58c851fff9401812b364fbe55fee9409c 0.0s done
#20 exporting attestation manifest sha256:42a24e8284ca9f5b5a5f92a1655c5b3abe05bce8d7c0e2c5511d3e265e7f7679 0.0s done
#20 exporting manifest list sha256:536c1467c6ac10bcce2a839f131f54ff9d27bc1d0d9fe3dd80a35204d814f9ef
#20 exporting manifest list sha256:536c1467c6ac10bcce2a839f131f54ff9d27bc1d0d9fe3dd80a35204d814f9ef 0.0s done
#20 naming to docker.io/library/nmvrmstest-client-prod:latest done
#20 unpacking to docker.io/library/nmvrmstest-client-prod:latest 0.1s done
#20 DONE 0.8s
Evidence: client/Dockerfile.prod build
#0 building with "mini2" instance using docker driver

#1 [internal] load build definition from Dockerfile.prod
#1 transferring dockerfile:
#1 transferring dockerfile: 801B 0.0s done
#1 DONE 0.2s

#2 [internal] load metadata for docker.io/library/nginx:latest
#2 ...

#3 [internal] load metadata for docker.io/library/node:24-alpine
#3 DONE 0.3s

#2 [internal] load metadata for docker.io/library/nginx:latest
#2 DONE 0.3s

#4 [internal] load .dockerignore
#4 transferring context: 335B 0.0s done
#4 DONE 0.0s

#5 [internal] load build context
#5 DONE 0.0s

#6 [client-production 1/3] FROM docker.io/library/nginx:latest@sha256:f9ea18bfa4fad859e1ed38259d711da7ccad2c3516e875cec3351a57c859f571
#6 resolve docker.io/library/nginx:latest@sha256:f9ea18bfa4fad859e1ed38259d711da7ccad2c3516e875cec3351a57c859f571 0.0s done
#6 DONE 0.0s

#7 [node-modules-install 1/6] FROM docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1
#7 resolve docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1 0.0s done
#7 DONE 0.0s

#7 [node-modules-install 1/6] FROM docker.io/library/node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1
#7 CACHED

#5 [internal] load build context
#5 transferring context: 2.29MB 0.3s done
#5 DONE 0.3s

#8 [node-modules-install 2/6] RUN mkdir /srv/client && chown node:node /srv/client
#8 DONE 0.7s

#9 [node-modules-install 3/6] WORKDIR /srv/client
#9 DONE 0.0s

#10 [node-modules-install 4/6] RUN mkdir -p node_modules
#10 DONE 0.1s

#11 [node-modules-install 5/6] COPY --chown=node:node client/package*.json ./
#11 DONE 0.0s

#12 [node-modules-install 6/6] RUN npm install --no-update-notifier
#12 34.93 npm warn deprecated babel-preset-es2015@6.24.1: 🙌  Thanks for using Babel: we recommend using babel-preset-env now: please read https://babeljs.io/env to update!
#12 50.55 npm warn deprecated core-js@2.6.12: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
#12 59.49 
#12 59.49 added 474 packages, and audited 475 packages in 59s
#12 59.49 
#12 59.49 82 packages are looking for funding
#12 59.49   run `npm fund` for details
#12 59.53 
#12 59.53 41 vulnerabilities (5 high, 36 critical)
#12 59.53 
#12 59.53 To address all issues possible (including breaking changes), run:
#12 59.53   npm audit fix --force
#12 59.53 
#12 59.53 Some issues need review, and may require choosing
#12 59.53 a different dependency.
#12 59.53 
#12 59.53 Run `npm audit` for details.
#12 59.53 npm warn install-scripts 4 packages have install scripts not yet covered by allowScripts:
#12 59.53 npm warn install-scripts   @swc/core@1.16.18 (postinstall: node postinstall.js)
#12 59.53 npm warn install-scripts   core-js@2.6.12 (postinstall: node -e "try{require('./postinstall')}catch(e){}")
#12 59.53 npm warn install-scripts   core-js@3.50.0 (postinstall: node -e "try{require('./postinstall')}catch(e){}")
#12 59.53 npm warn install-scripts   @parcel/watcher@2.6.0 (install: node scripts/build-from-source.js)
#12 59.53 npm warn install-scripts
#12 59.53 npm warn install-scripts Run `npm install-scripts ls` to review, or `npm install-scripts approve <pkg>` to allow.
#12 DONE 62.0s

#13 [client-builder 2/6] WORKDIR /srv/client
#13 CACHED

#14 [client-builder 3/6] COPY --from=node-modules-install /srv/client/node_modules node_modules
#14 DONE 16.3s

#15 [client-builder 4/6] COPY client/. .
#15 DONE 0.4s

#16 [client-builder 5/6] COPY shared/ /srv/shared/
#16 DONE 0.0s

#17 [client-builder 6/6] RUN npm run build
#17 0.518 
#17 0.518 > vrms-client@0.3.0 build
#17 0.518 > vite build
#17 0.518 
#17 1.080 vite v8.3.4 building client environment for production...
#17 1.092 transforming...
#17 3.006 ✓ 2097 modules transformed.
#17 3.194 rendering chunks...
#17 3.459 computing gzip size...
#17 3.477 build/index.html                                              2.04 kB │ gzip:   0.94 kB
#17 3.477 build/assets/hflalogo-DAcrAwfK.svg                            6.30 kB │ gzip:   4.74 kB
#17 3.477 build/assets/aliseo-noncommercial-webfont-CvedmeaU.woff2     10.56 kB
#17 3.477 build/assets/aliseo-noncommercial-webfont-D44uqgp9.woff      13.64 kB
#17 3.477 build/assets/22-gaIIUNhE.gif                                 24.19 kB
#17 3.477 build/assets/index-BlxpJTLx.css                              54.85 kB │ gzip:   9.75 kB
#17 3.477 build/assets/index-CMBD5rSU.js                            1,495.50 kB │ gzip: 457.54 kB
#17 3.477 
#17 3.486 [plugin builtin:vite-reporter] 
#17 3.486 (!) Some chunks are larger than 500 kB after minification. Consider:
#17 3.486 - Using dynamic import() to code-split the application
#17 3.486 - Use build.rolldownOptions.output.codeSplitting to improve chunking: https://rolldown.rs/reference/OutputOptions.codeSplitting
#17 3.486 - Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
#17 3.487 �[33m[COMMONJS_VARIABLE_IN_ESM] �[0mThe CommonJS `module` variable is treated as a global variable in an ECMAScript module and may not work as expected
#17 3.487     �[38;5;246m╭�[0m�[38;5;246m─�[0m�[38;5;246m[�[0m ../shared/roles.js:22:3 �[38;5;246m]�[0m
#17 3.487     �[38;5;246m│�[0m
#17 3.487  �[38;5;246m22 │�[0m �[38;5;249m �[0m�[38;5;249m �[0mmodule�[38;5;249m.�[0m�[38;5;249me�[0m�[38;5;249mx�[0m�[38;5;249mp�[0m�[38;5;249mo�[0m�[38;5;249mr�[0m�[38;5;249mt�[0m�[38;5;249ms�[0m�[38;5;249m �[0m�[38;5;249m=�[0m�[38;5;249m �[0m�[38;5;249m{�[0m
#17 3.487  �[38;5;240m   │�[0m   ───┬──  
#17 3.487  �[38;5;240m   │�[0m      ╰──── 
#17 3.487  �[38;5;240m   │�[0m 
#17 3.487  �[38;5;246m29 │�[0m export�[38;5;249m �[0m�[38;5;249m{�[0m�[38;5;249m �[0m�[38;5;249mR�[0m�[38;5;249mO�[0m�[38;5;249mL�[0m�[38;5;249mE�[0m�[38;5;249mS�[0m�[38;5;249m,�[0m�[38;5;249m �[0m�[38;5;249mR�[0m�[38;5;249mO�[0m�[38;5;249mL�[0m�[38;5;249mE�[0m�[38;5;249m_�[0m�[38;5;249mH�[0m�[38;5;249mI�[0m�[38;5;249mE�[0m�[38;5;249mR�[0m�[38;5;249mA�[0m�[38;5;249mR�[0m�[38;5;249mC�[0m�[38;5;249mH�[0m�[38;5;249mY�[0m�[38;5;249m �[0m�[38;5;249m}�[0m�[38;5;249m;�[0m
#17 3.487  �[38;5;240m   │�[0m ───┬──  
#17 3.487  �[38;5;240m   │�[0m    ╰──── This file is considered to be an ECMAScript module because of the `export` keyword here:
#17 3.487 �[38;5;246m────╯�[0m
#17 3.487 
#17 3.488 �[33m[COMMONJS_VARIABLE_IN_ESM] �[0mThe CommonJS `module` variable is treated as a global variable in an ECMAScript module and may not work as expected
#17 3.488     �[38;5;246m╭�[0m�[38;5;246m─�[0m�[38;5;246m[�[0m ../shared/authorizationUtils.js:36:3 �[38;5;246m]�[0m
#17 3.488     �[38;5;246m│�[0m
#17 3.488  �[38;5;246m36 │�[0m �[38;5;249m �[0m�[38;5;249m �[0mmodule�[38;5;249m.�[0m�[38;5;249me�[0m�[38;5;249mx�[0m�[38;5;249mp�[0m�[38;5;249mo�[0m�[38;5;249mr�[0m�[38;5;249mt�[0m�[38;5;249ms�[0m�[38;5;249m �[0m�[38;5;249m=�[0m�[38;5;249m �[0m�[38;5;249m{�[0m
#17 3.488  �[38;5;240m   │�[0m   ───┬──  
#17 3.488  �[38;5;240m   │�[0m      ╰──── 
#17 3.488  �[38;5;240m   │�[0m 
#17 3.488  �[38;5;246m47 │�[0m export�[38;5;249m �[0m�[38;5;249m{�[0m
#17 3.488  �[38;5;240m   │�[0m ───┬──  
#17 3.488  �[38;5;240m   │�[0m    ╰──── This file is considered to be an ECMAScript module because of the `export` keyword here:
#17 3.488 �[38;5;246m────╯�[0m
#17 3.488 
#17 3.507 ✓ built in 2.42s
#17 3.581 npm notice
#17 3.581 npm notice New major version of npm available! 11.19.0 -> 12.2.0
#17 3.581 npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0
#17 3.581 npm notice To update run: npm install -g npm@12.2.0
#17 3.581 npm notice
#17 DONE 3.7s

#18 [client-production 2/3] COPY client/nginx/default.conf /etc/nginx/conf.d/default.conf
#18 CACHED

#19 [client-production 3/3] COPY --from=client-builder /srv/client/build /usr/share/nginx/html/
#19 CACHED

#20 exporting to image
#20 exporting layers done
#20 exporting manifest sha256:21a9e453a65331ce4e62cf778aa65ff506f61674392d7d99fa214030d800aeda done
#20 exporting config sha256:e3830e7af0345a8f243174a8e8dcf6c58c851fff9401812b364fbe55fee9409c done
#20 exporting attestation manifest sha256:2b18b9b32242c1762f55b86f17f79b6cb624f1d902cd349116f9e26511908366 0.0s done
#20 exporting manifest list sha256:12db9bfada0329fcb9684eae6d4e4878c631152fe89fc6c46f8ed7b46b9a5a1c done
#20 naming to docker.io/library/nmvrmstest-client-prod2:latest done
#20 unpacking to docker.io/library/nmvrmstest-client-prod2:latest done
#20 DONE 0.1s
  • Evidence: API production image build (local file: ~/.no-mistakes/evidence/01M4SH8X5ZGVJ4KZE599604F8S/api-prod-build.log)
Evidence: Live API transcript (date[$gt]/[$lt] filters, 404 splat, header guard)

GET /api/events/?date[$gt]=2025-01-01 -> [Future Event, Ready Event] GET /api/events/?date[$lt]=2025-01-01 -> [Past Event] GET /api/does-not-exist -> HTTP 404 GET /api/events/ (no header) -> HTTP 401

# Backend running in docker compose (Express 5, mongoose 9, node 24) against throwaway mongo:7
$ GET /api/events/   # unfiltered
[{"name":"Past Event","date":"2020-01-01T00:00:00.000Z"},{"name":"Future Event","date":"2099-01-01T00:00:00.000Z"},{"name":"Ready Event","date":"2026-10-13T02:43:13.395Z"}]
$ GET /api/events/?date[$gt]=2025-01-01T00:00:00.000Z   # bracket operator, as EventsApiService sends
[{"name":"Future Event","date":"2099-01-01T00:00:00.000Z"},{"name":"Ready Event","date":"2026-10-13T02:43:13.395Z"}]
$ GET /api/events/?date[$lt]=2025-01-01T00:00:00.000Z
[{"name":"Past Event","date":"2020-01-01T00:00:00.000Z"}]
$ GET /api/events/?checkInReady=true
["Ready Event"]
$ GET /api/does-not-exist   # Express 5 /{*splat} catch-all
HTTP 404
$ GET /some/deep/unknown/path
HTTP 404
$ GET /api/events/ without custom header   # guard still enforced
HTTP 401
$ GET /api/healthcheck
I'm Alive! Build: unknown | Built: 2026-10-13T02:43:30.637Z | Checked: 2026-10-13T02:43:57.492Z
$ GET /api/projects/
[{"name":"NM Test Project","projectStatus":"Active"}]
Evidence: Installed versions in running containers
# backend container (node v24.21.0)
express 5.3.0
mongoose 9.11.2
@slack/bolt 5.1.0
googleapis 185.0.0
dotenv 18.0.7
dotenv-expand 13.0.0
# client container (node v24.21.0)
react 19.3.0
react-dom 19.3.0
react-router 7.18.4
@mui/material 9.5.0
@mui/x-date-pickers 9.15.0
vite 8.3.4
d3 7.9.0
![Home page (React 19 / router 7)](https://github.com/user-attachments/assets/42bb92f1-69bb-4224-a01f-3184eb6b8845) ![Login page](https://github.com/user-attachments/assets/6f49d2d7-8b0f-46bc-a225-917de5da3e49) ![/new check-in event list](https://github.com/user-attachments/assets/439f086a-db4c-4e9a-9244-a94161f8d516) ![/returning check-in event list](https://github.com/user-attachments/assets/b9ea9cbb-4c5e-4d5c-8d0a-60b38ba3881d) ![Unknown route redirected to home](https://github.com/user-attachments/assets/b8d5c425-fefd-4b40-8e61-55b3c03ea0d6) ![New-user check-in DatePicker, empty](https://github.com/user-attachments/assets/5d165087-bcb6-44db-8174-168905d79c26) ![New-user check-in DatePicker, open year view](https://github.com/user-attachments/assets/3cc91969-7be1-44ea-b949-b8c83993c4fa) ![New-user check-in DatePicker, March 2023 selected in red semi-bold](https://github.com/user-attachments/assets/0ae1f75b-28d1-40ae-b56c-069d596adef2) - Evidence: event.integration.test.js run inside backend container (local file: ~/.no-mistakes/evidence/01M4SH8X5ZGVJ4KZE599604F8S/event-integration-test.txt)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 1 info
  • 🚨 backend/app.js:55 - Express 5 switched the default query parser from 'extended' (qs) to 'simple' (querystring), and this change doesn't set it back. The client still sends bracket-style operator queries: client/src/api/EventsApiService.js:18 builds /api/events/?date[$gt]=&lt;iso&gt;, which ManageProjects.jsx:61 uses through EventsApiService.fetchEvents(). Under Express 4, req.query was { date: { $gt: &#39;...&#39; } }. Under Express 5 it is { &#39;date[$gt]&#39;: &#39;...&#39; }, and EventController.event_list (backend/controllers/event.controller.js:6-9) passes that straight to Event.find(query). Mongoose's default strictQuery is false, so it queries a field literally named date[$gt] and returns [] without any error. The project management page then silently shows no events. Every other handler that hands req.query to find loses nested/bracket query support the same way: backend/controllers/user.controller.js:22-29 (User.find(query)) and backend/controllers/project.controller.js:7-10 (Project.find(query)). Fix: right after const app = express();, add app.set(&#39;query parser&#39;, &#39;extended&#39;) (and qs if needed). That restores the Express 4 behavior at the one shared boundary every caller goes through. Alternatively, parse the date filter explicitly in event_list.
  • ⚠️ client/src/components/presentational/newUserForm.jsx:218 - After the move to @mui/x-date-pickers 9, the DatePicker uses the accessible field DOM structure by default (enableAccessibleFieldDOMStructure is true from v8 onward). The visible field is now made of section spans, not a text &lt;input&gt;. So the sx selector &#39;&amp; input[type=text]&#39; (height 40px, red rgb(250, 17, 79), semi-bold, no bottom border) no longer matches anything. The Month/Year picker on the new-user check-in form loses its custom styling without any error. Fix: pass enableAccessibleFieldDOMStructure={false} to keep the old input-based field, or retarget the styles to .MuiPickersSectionList-root / .MuiPickersInputBase-root.
  • ℹ️ docker-compose.yml:13 - This one matters for the intent ('make sure that the service builds into our dockerized coder workspace'). docker-compose mounts named volumes backend_node_modules and client_node_modules over /srv/*/node_modules. Docker only fills a named volume from the image when the volume is empty. An existing Coder workspace that runs docker compose up --build will rebuild the images but keep the old Express 4 / React 18 / react-router 5 node_modules. The migrated code (Routes/Navigate, createRoot, /{*splat}) would then fail at runtime. The compose file itself is pre-existing and unchanged. Existing workspaces need docker compose down -v (or the volumes removed) once after this bump, so this should be called out in the PR or upgrade notes.

🔧 Fix applied.
1 info still open:

  • ℹ️ docker-compose.yml:13 - This one matters for the intent ('make sure that the service builds into our dockerized coder workspace'). docker-compose mounts named volumes backend_node_modules and client_node_modules over /srv/*/node_modules. Docker only fills a named volume from the image when the volume is empty. An existing Coder workspace that runs docker compose up --build will rebuild the images but keep the old Express 4 / React 18 / react-router 5 node_modules. The migrated code (Routes/Navigate, createRoot, /{*splat}) would then fail at runtime. The compose file itself is pre-existing and unchanged. Existing workspaces need docker compose down -v (or the volumes removed) once after this bump, so this should be called out in the PR or upgrade notes.
✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 7 of 7 scenarios driven live against the product
Scenario Result Live Evidence
Developer runs docker compose build from the repo root and the backend and client dev images build on Node 24 with the bumped lockfiles ✅ pass live compose-build.log (both images Built, exit 0); installed-versions.txt
Production image targets (client-production via Dockerfile.client and Dockerfile.prod, api-production) build, including the vite 8 production build ✅ pass live client-prod-build.log ('built in 5.80s'), client-dockerfile-prod-build.log, api-prod-build.log (all exit 0)
Backend boots in compose on Express 5 / mongoose 9 / dotenv-expand 13, connects to Mongo and answers the healthcheck ✅ pass live api-transcript.txt (healthcheck 'I'm Alive!'); container log 'Mongoose connected ... listening on 4000'
Project-management events query with date[$gt] still filters under Express 5 (extended query parser restored) ✅ pass live api-transcript.txt: date[$gt]=2025 returns only future events, date[$lt] returns only Past Event; event-integration-test.txt passes
Adversarial: unknown API and deep paths hit the Express 5 /{*splat} 404 fallback, and requests without the custom header are still rejected ✅ pass live api-transcript.txt: /api/does-not-exist -> 404, /some/deep/unknown/path -> 404, no header -> 401
Client dev server (vite 8, React 19 createRoot, react-router 7) renders home, login, /new and /returning with live events, and an unknown route redirects to / ✅ pass live home.png, login.png, new.png, returning.png, unknown-route.png; Playwright log shows the unknown route ends at '/'
New-user check-in Month/Year DatePicker on MUI x-date-pickers 9 keeps its custom look and lets the user pick a date that enables CHECK IN ✅ pass live checkin-newuser-datepicker-{empty,open,selected}.png; computed style color rgb(250, 17, 79), fontWeight 600, height 40px; value 'March 2023'; CHECK IN enabled
  • docker compose -p nmvrmstest build backend client (repo docker-compose.yml, root build context, Node 24)
  • docker build -f client/Dockerfile.client --target client-production . (vite 8 production build)
  • docker build -f client/Dockerfile.prod --target client-production .
  • docker build -f backend/Dockerfile.api --target api-production .
  • docker compose up mongo backend client with a disposable override: mongo:7 service, source baked into images because the daemon is remote (ssh://mini2), throwaway .env files
  • curl against the running backend: GET /api/events (unfiltered, date[$gt], date[$lt], checkInReady), unknown /api and deep paths for the 404 fallback, the missing-header guard, /api/healthcheck, /api/projects
  • Playwright (in a container sharing the client's network) loading /, /login, /new, /returning, an unknown route, and /checkIn/newUser with screenshots
  • Playwright DatePicker flow: choose 'No' on the first-time question, check computed styles of .MuiPickersInputBase-sectionsContainer, open the picker, pick 2023 then March, confirm the CHECK IN button is enabled
  • npx vitest run test/event.integration.test.js inside the built backend container (MONGOMS_DISTRO=ubuntu-22.04)
  • Recorded installed dependency versions inside the running containers
✅ **Document** - passed

✅ No issues found.

⚠️ **Lint** - 1 info
  • ℹ️ backend/app.js:3 - Biome 2.5.15 still reports error-level diagnostics in files this change touched, and none of them come from this change. (1) assist/source/organizeImports in backend/app.js and backend/env.bootstrap.js. The import order there is old, and in app.js the side-effect imports are mixed in with statements (assertEnv, workers, cleanupExpiredTokens), so sorting automatically could change load order. (2) lint/suspicious/noArrayIndexKey in client/src/components/manageProjects/editPMs/projectMembersList.jsx:178 and client/src/components/user-admin/UserPermissionSearch.jsx:38,76. Fixing these needs stable keys, which is a behavior change. These were left as they are: the repo's lint-staged hook runs biome check --write ... || true, so it does not block commits on them.
✅ **Push** - passed

✅ No issues found.

@github-actions

Copy link
Copy Markdown

Want to review this pull request? Take a look at this documentation for a step by step guide!

From your project repository, check out a new branch and test the changes.

git checkout -b hackforla-chore/vrms-deps-bump development
git pull https://github.com/hackforla/VRMS.git chore/vrms-deps-bump

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant