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 .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v26.5.1
26.12.1
12 changes: 7 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# syntax=docker/dockerfile:1

ARG NODE_VERSION=26.5.1
ARG NODE_VERSION=26.12.1
ARG ALPINE_VERSION=3.24

FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS build
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION}@sha256:40cd011b55415bc894e45b02fdd5a5dfde056921b7d23a64c74f80497af48797 AS build

ARG PNPM_VERSION=10.28.2
ARG PNPM_VERSION=11.15.1

ENV CI=true
ENV PRISMA_CLI_BINARY_TARGETS=linux-musl-openssl-3.0.x
Expand All @@ -19,16 +19,18 @@ RUN apk upgrade --no-cache \
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml nest-cli.json tsconfig.json tsconfig.build.json \
eslint.config.mjs .prettierrc ./
COPY packages/projects-prisma-client/package.json ./packages/projects-prisma-client/package.json
COPY patches ./patches
COPY tools ./tools
COPY prisma ./prisma
RUN pnpm install --frozen-lockfile

COPY . .
RUN pnpm lint \
&& pnpm test --runInBand \
&& pnpm test:dependency-compat \
&& pnpm build \
&& pnpm prune --prod --ignore-scripts

FROM alpine:${ALPINE_VERSION} AS production
FROM alpine:${ALPINE_VERSION}@sha256:be2656061b536c1883c4034790e21d0a09c5aaaf51968b89368a3c0371ea2c9a AS production

ARG NODE_VERSION
ARG RESET_DB_ARG=false
Expand Down
23 changes: 16 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
NestJS drop-in replacement for `tc-project-service`, serving the Topcoder platform at `/v6/projects`.

[![CircleCI](https://img.shields.io/badge/CircleCI-build%20status-informational?logo=circleci)](https://circleci.com/)
![Node](https://img.shields.io/badge/node-v26.5.1-339933?logo=node.js&logoColor=white)
![pnpm](https://img.shields.io/badge/pnpm-10.28.2-F69220?logo=pnpm&logoColor=white)
![Node](https://img.shields.io/badge/node-v26.12.1-339933?logo=node.js&logoColor=white)
![pnpm](https://img.shields.io/badge/pnpm-11.15.1-F69220?logo=pnpm&logoColor=white)
![Audit](https://img.shields.io/badge/production%20audit-0%20findings-brightgreen)

## Table of Contents
Expand Down Expand Up @@ -419,8 +419,8 @@ Reference source: `.env.example`.

### Prerequisites

- Node.js `v26.5.1` (`nvm use` in this project folder)
- pnpm `10.28.2`
- Node.js `v26.12.1` (`nvm use` in this project folder)
- pnpm `11.15.1`
- PostgreSQL

### Installation
Expand Down Expand Up @@ -486,7 +486,7 @@ Must pass before every commit per `AGENTS.md`.
## Deployment

- CI/CD: CircleCI -> AWS ECS Fargate.
- The multi-stage Docker image builds with Node 26.5.1 and copies only compiled
- The multi-stage Docker image builds with Node 26.12.1 and copies only compiled
output, production dependencies, and Prisma migration assets into its Alpine
3.24 runtime. The runtime installs the dynamically linked Alpine Node package
and does not contain npm or other package tooling.
Expand Down Expand Up @@ -517,8 +517,8 @@ Open findings are tracked inline with `TODO (security)` comments in source.
Summary from `docs/DEPENDENCIES.md`:

- Production audit: no known vulnerabilities.
- Node 26.5.1, NestJS 11.1.28, Prisma 7.9.0, Axios 1.18.1,
Lodash 4.18.1, qs 6.15.3, and UUID 14.0.1 are locked in the
- Node 26.12.1, NestJS 11.2.8, Prisma 7.10.1, Axios 1.21.0,
Lodash 4.18.1, qs 6.17.1, and UUID 14.0.3 are locked in the
security candidate.
- Security overrides for affected transitives are maintained in
`pnpm-workspace.yaml` and captured in `pnpm-lock.yaml`.
Expand Down Expand Up @@ -606,3 +606,12 @@ Node major. The runtime keeps Alpine's dynamically linked Node and system
libraries. Existing non-root users and application entrypoints are preserved.
Build stages using a versioned official Node image retain their configured
version, and pnpm build arguments are explicitly declared in the consuming stage.

## November 2026 security validation

The dependency refresh updates the complete lockfile, pins the reviewed core
library revision, and tests legacy minimatch consumers through
`pnpm test:dependency-compat`. Patched Ajv 6 and 8 dependencies replace the
obsolete ESLint patches that forced a different Ajv major. Salesforce fallback
queries now log a fixed diagnostic message rather than SQL containing
configuration fields or account identifiers.
95 changes: 48 additions & 47 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,70 +21,71 @@
"test:load": "jest --config ./test/jest-e2e.json --runInBand --testRegex \"test/load/performance.test.ts$\"",
"test:deployment": "jest --config ./test/jest-e2e.json --runInBand test/deployment-validation.e2e-spec.ts",
"deploy:dev": "BRANCH=$(git rev-parse --abbrev-ref HEAD) && TAG=\"dev-${BRANCH}\" && git tag -d \"$TAG\" 2>/dev/null; git push origin \":refs/tags/$TAG\" 2>/dev/null; git tag \"$TAG\" && git push origin \"$TAG\"",
"postinstall": "pnpm exec prisma generate"
"postinstall": "pnpm exec prisma generate",
"test:dependency-compat": "node --test tools/minimatch-compat/index.test.cjs"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.1090.0",
"@aws-sdk/cloudfront-signer": "^3.1088.0",
"@aws-sdk/s3-request-presigner": "^3.1090.0",
"@aws-sdk/client-s3": "^3.1161.0",
"@aws-sdk/cloudfront-signer": "^3.1161.0",
"@aws-sdk/s3-request-presigner": "^3.1161.0",
"@nestjs/axios": "^4.0.1",
"@nestjs/common": "^11.1.28",
"@nestjs/core": "^11.1.28",
"@nestjs/mapped-types": "^2.1.0",
"@nestjs/platform-express": "^11.1.28",
"@nestjs/swagger": "^11.4.6",
"@prisma/adapter-pg": "7.9.0",
"@prisma/client": "7.9.0",
"@nestjs/common": "^11.2.8",
"@nestjs/core": "^11.2.8",
"@nestjs/mapped-types": "^2.1.1",
"@nestjs/platform-express": "^11.2.8",
"@nestjs/swagger": "^11.4.7",
"@prisma/adapter-pg": "7.10.1",
"@prisma/client": "7.10.1",
"@topcoder/challenge-api-v6": "github:topcoder-platform/challenge-api-v6#8ca7e4d065d15a077c648e4d04b85b73276cc078&path:packages/challenge-prisma-client",
"@topcoder/member-api-v6": "github:topcoder-platform/member-api-v6#a0ffd68bd7c63bbf525459b1e195d6d38ab26a91&path:packages/member-prisma-client",
"@topcoder/resource-api-v6": "github:topcoder-platform/resource-api-v6#c64ffdccbed62533528dce55d33484be5e035d89&path:packages/resources-prisma-client",
"@topcoder/standardized-skills-api": "github:topcoder-platform/standardized-skills-api#012bf813583f80ec1dad014824ebb4d0bd434439&path:packages/skills-prisma-client",
"axios": "^1.18.1",
"axios": "1.21.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"cors": "^2.8.5",
"jsonwebtoken": "^9.0.2",
"jwks-rsa": "^3.2.0",
"lodash": "^4.18.1",
"prisma": "7.9.0",
"qs": "^6.15.3",
"class-validator": "^0.14.4",
"cors": "^2.8.6",
"jsonwebtoken": "^9.0.3",
"jwks-rsa": "^3.2.2",
"lodash": "4.18.1",
"prisma": "7.10.1",
"qs": "6.17.1",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
"tc-core-library-js": "github:topcoder-platform/tc-core-library-js#v4.0.0-rc.1",
"uuid": "^14.0.1",
"winston": "^3.17.0"
"rxjs": "^7.8.2",
"tc-core-library-js": "https://codeload.github.com/topcoder-platform/tc-core-library-js/tar.gz/a25576b8b038211d1ba910eca2d900271ba6659d",
"uuid": "^14.0.3",
"winston": "^3.19.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "^9.18.0",
"@nestjs/cli": "^11.0.0",
"@nestjs/schematics": "^11.0.0",
"@nestjs/testing": "^11.1.28",
"@swc/cli": "^0.6.0",
"@swc/core": "^1.10.7",
"@eslint/eslintrc": "^3.3.7",
"@eslint/js": "^9.39.5",
"@nestjs/cli": "^11.0.24",
"@nestjs/schematics": "^11.1.0",
"@nestjs/testing": "^11.2.8",
"@swc/cli": "^0.8.2",
"@swc/core": "^1.16.21",
"@types/autocannon": "^7.12.7",
"@types/express": "^5.0.0",
"@types/express": "^5.0.6",
"@types/jest": "^29.5.14",
"@types/jsonwebtoken": "^9.0.9",
"@types/lodash": "^4.17.20",
"@types/node": "^26.1.1",
"@types/supertest": "^6.0.2",
"ajv": "^8.18.0",
"@types/jsonwebtoken": "^9.0.10",
"@types/lodash": "^4.17.27",
"@types/node": "^26.6.6",
"@types/supertest": "^6.0.3",
"ajv": "8.18.0",
"autocannon": "^8.0.0",
"eslint": "^9.18.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-prettier": "^5.2.2",
"globals": "^15.14.0",
"eslint": "^9.39.5",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.7",
"globals": "^15.15.0",
"jest": "^29.7.0",
"prettier": "^3.4.2",
"prettier": "^3.9.10",
"source-map-support": "^0.5.21",
"supertest": "^7.0.0",
"ts-jest": "^29.2.5",
"ts-loader": "^9.5.2",
"supertest": "^7.3.1",
"ts-jest": "^29.4.15",
"ts-loader": "^9.6.2",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.64.0"
"typescript-eslint": "^8.72.1"
},
"prisma": {
"seed": "ts-node prisma/seed.ts"
Expand All @@ -106,11 +107,11 @@
"coverageDirectory": "../coverage",
"testEnvironment": "node"
},
"packageManager": "pnpm@10.28.2+sha512.41872f037ad22f7348e3b1debbaf7e867cfd448f2726d9cf74c08f19507c31d2c8e7a11525b983febc2df640b5438dee6023ebb1f84ed43cc2d654d2bc326264",
"packageManager": "pnpm@11.15.1",
"engines": {
"node": "26.x"
},
"volta": {
"node": "26.5.1"
"node": "26.12.1"
}
}
2 changes: 1 addition & 1 deletion packages/projects-prisma-client/generated/client.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

/* !!! This is code generated by Prisma. Do not edit directly. !!!
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
/* eslint-disable */
// biome-ignore-all lint: generated file
module.exports = { ...require('.') }
2 changes: 1 addition & 1 deletion packages/projects-prisma-client/generated/default.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

/* !!! This is code generated by Prisma. Do not edit directly. !!!
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
/* eslint-disable */
// biome-ignore-all lint: generated file
module.exports = { ...require('#main-entry-point') }
16 changes: 8 additions & 8 deletions packages/projects-prisma-client/generated/edge.js

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions packages/projects-prisma-client/generated/index-browser.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

/* !!! This is code generated by Prisma. Do not edit directly. !!!
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
/* eslint-disable */
// biome-ignore-all lint: generated file

Expand All @@ -24,12 +24,12 @@ exports.Prisma = Prisma
exports.$Enums = {}

/**
* Prisma Client JS version: 7.9.0
* Query Engine version: e922089b7d7502aff4249d5da3420f6fa55fc6ad
* Prisma Client JS version: 7.10.1
* Query Engine version: d1b3f377ca835d73fd50954a5e22128b9ebdd6b8
*/
Prisma.prismaVersion = {
client: "7.9.0",
engine: "e922089b7d7502aff4249d5da3420f6fa55fc6ad"
client: "7.10.1",
engine: "d1b3f377ca835d73fd50954a5e22128b9ebdd6b8"
}

Prisma.PrismaClientKnownRequestError = () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/projects-prisma-client/generated/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1163,8 +1163,8 @@ export namespace Prisma {
export import Exact = $Public.Exact

/**
* Prisma Client JS version: 7.9.0
* Query Engine version: e922089b7d7502aff4249d5da3420f6fa55fc6ad
* Prisma Client JS version: 7.10.1
* Query Engine version: d1b3f377ca835d73fd50954a5e22128b9ebdd6b8
*/
export type PrismaVersion = {
client: string
Expand Down
16 changes: 8 additions & 8 deletions packages/projects-prisma-client/generated/index.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/projects-prisma-client/generated/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@
},
"./*": "./*"
},
"version": "7.9.0",
"version": "7.10.1",
"sideEffects": false,
"dependencies": {
"@prisma/client-runtime-utils": "7.9.0"
"@prisma/client-runtime-utils": "7.10.1"
},
"imports": {
"#wasm-compiler-loader": {
Expand Down
Binary file not shown.

Large diffs are not rendered by default.

Loading
Loading