8b77656bb7
Bring backend and frontend to the latest stable releases (no pre-releases), including major upgrades that required code migration. Both projects pass typecheck and production builds. Backend - NestJS 10 -> 11 (common/core/platform-express/jwt/passport/bull/cli/ schematics/testing), @nestjs/config 3->4, @nestjs/swagger 7->11, @nestjs/typeorm 10->11 - @kubernetes/client-node 0.21 -> 1.4: migrate ~200+ call sites across 6 services to the v1 single-object argument API, unwrapped responses, err.code, setHeaderOptions for patch content-type, applyToHTTPSOptions. Add regression spec k8s-client-v1-migration.spec.ts. - typeorm 0.3 -> 1.0: relations/select string arrays -> object form - uuid 9->14 (drops @types/uuid), multer 1->2, bcrypt 5->6, helmet 7->8, class-validator 0.14->0.15 - TypeScript 5->6, ESLint 8->9, @typescript-eslint 6->8, jest 29->30, @types/node 20->24; tsconfig: strictPropertyInitialization:false, ignoreDeprecations, rootDir, explicit types[] - @nestjs/config 4: jwt.strategy uses getOrThrow; @types/express kept at 4 (Nest 11 runs Express 4) Frontend - React 18->19, Next 14->16 (async params via official codemod), Tailwind 3->4 (@tailwindcss/postcss, @import + @config, inline custom @apply), framer-motion 11->12, zustand 4->5, three 0.169->0.184, @react-three/* majors - TypeScript 5->6 (tsconfig target es5->ES2017), ESLint 8->9, eslint-config-next 14->16 Infra/docs - Dockerfiles node:20-alpine -> node:24-alpine (require-esm for k8s client) - Add UPGRADE.md / UPGRADE.en.md; refresh README tech-stack versions Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
162 lines
9.5 KiB
Markdown
162 lines
9.5 KiB
Markdown
# ارتقای وابستگیها به آخرین نسخههای استیبل
|
||
|
||
برنچ: `chore/upgrade-dependencies-latest` (از روی `feat/abrban-landing`)
|
||
🌐 English version: [UPGRADE.en.md](UPGRADE.en.md)
|
||
|
||
تمام وابستگیهای backend و frontend به **آخرین نسخهی استیبل** (نه pre-release) ارتقا یافتند،
|
||
شامل ارتقاهای major که نیاز به migration کد داشتند. هر دو پروژه build و typecheck سبز دارند.
|
||
|
||
---
|
||
|
||
## خلاصهی وضعیت
|
||
|
||
| پروژه | typecheck | build | تستها |
|
||
|---|---|---|---|
|
||
| **backend** | ✅ `tsc` صفر خطا | ✅ `nest build` | ۹۵/۹۶ پاس (۱ شکستِ از-پیش-موجودِ helm، بیربط) + ۶ تست جدیدِ migration |
|
||
| **frontend** | ✅ `tsc` صفر خطا | ✅ `next build` (۴۲ مسیر) | — |
|
||
|
||
> **حداقل نسخهی Node در runtime: ۲۰.۱۹** (بهخاطر ESMبودنِ `@kubernetes/client-node@1`). Dockerfileها به `node:24-alpine` (LTS) ارتقا یافتند.
|
||
|
||
---
|
||
|
||
## Backend — `dependencies`
|
||
|
||
| بسته | قبل | بعد | نوع |
|
||
|---|---|---|---|
|
||
| `@kubernetes/client-node` | `^0.21.0` | `^1.4.0` | **major** |
|
||
| `@nestjs/bull` | `^10.1.0` | `^11.0.4` | major |
|
||
| `@nestjs/common` | `^10.3.0` | `^11.1.24` | major |
|
||
| `@nestjs/config` | `^3.1.0` | `^4.0.4` | major |
|
||
| `@nestjs/core` | `^10.3.0` | `^11.1.26` | major |
|
||
| `@nestjs/jwt` | `^10.2.0` | `^11.0.2` | major |
|
||
| `@nestjs/passport` | `^10.0.3` | `^11.0.5` | major |
|
||
| `@nestjs/platform-express` | `^10.3.0` | `^11.1.26` | major |
|
||
| `@nestjs/swagger` | `^7.2.0` | `^11.4.4` | major |
|
||
| `@nestjs/typeorm` | `^10.0.1` | `^11.0.1` | major |
|
||
| `bcrypt` | `^5.1.1` | `^6.0.0` | major |
|
||
| `class-validator` | `^0.14.1` | `^0.15.1` | minor (0.x) |
|
||
| `helmet` | `^7.1.0` | `^8.2.0` | major |
|
||
| `js-yaml` | `^4.1.0` | `^4.2.0` | minor |
|
||
| `multer` | `^1.4.5-lts.1` | `^2.1.1` | **major** |
|
||
| `pg` | `^8.11.0` | `^8.21.0` | minor |
|
||
| `rxjs` | `^7.8.1` | `^7.8.2` | patch (۸ هنوز استیبل نیست) |
|
||
| `typeorm` | `^0.3.19` | `^1.0.0` | **major** |
|
||
| `uuid` | `^9.0.0` | `^14.0.0` | **major** |
|
||
|
||
بدون تغییر (از قبل آخرین استیبل): `bull`, `class-transformer`, `handlebars`, `passport`, `passport-jwt`, `reflect-metadata`.
|
||
|
||
## Backend — `devDependencies`
|
||
|
||
| بسته | قبل | بعد |
|
||
|---|---|---|
|
||
| `@nestjs/cli` | `^10.3.0` | `^11.0.23` |
|
||
| `@nestjs/schematics` | `^10.1.0` | `^11.1.0` |
|
||
| `@nestjs/testing` | `^10.3.0` | `^11.1.26` |
|
||
| `@types/bcrypt` | `^5.0.2` | `^6.0.0` |
|
||
| `@types/jest` | `^29.5.11` | `^30.0.0` |
|
||
| `@types/multer` | `^1.4.11` | `^2.1.0` |
|
||
| `@types/node` | `^20.11.0` | `^24.0.0` |
|
||
| `@typescript-eslint/eslint-plugin` | `^6.19.0` | `^8.61.0` |
|
||
| `@typescript-eslint/parser` | `^6.19.0` | `^8.61.0` |
|
||
| `eslint` | `^8.56.0` | `^9.0.0` |
|
||
| `jest` | `^29.7.0` | `^30.4.2` |
|
||
| `prettier` | `^3.2.0` | `^3.8.4` |
|
||
| `ts-jest` | `^29.1.1` | `^29.4.11` |
|
||
| `typescript` | `^5.3.3` | `^6.0.0` |
|
||
| `@types/uuid` | `^9.0.7` | **حذف شد** (`uuid@14` تایپهایش را خودش دارد) |
|
||
|
||
> **`@types/express` عمداً روی `^4.17.21` نگه داشته شد**: NestJS 11 در runtime روی Express **۴** اجرا میشود؛ `@types/express@5` فقط با Express 5 سازگار است.
|
||
|
||
---
|
||
|
||
## Frontend — `dependencies`
|
||
|
||
| بسته | قبل | بعد | نوع |
|
||
|---|---|---|---|
|
||
| `react` | `^18.2.0` | `^19.2.7` | **major** |
|
||
| `react-dom` | `^18.2.0` | `^19.2.7` | **major** |
|
||
| `next` | `14.1.0` | `16.2.9` | **major (۲ نسخه)** |
|
||
| `tailwindcss`* | `^3.4.1` | `^4.3.1` | **major** |
|
||
| `framer-motion` | `^11.18.2` | `^12.40.0` | **major** |
|
||
| `zustand` | `^4.5.0` | `^5.0.14` | **major** |
|
||
| `three` | `^0.169.0` | `^0.184.0` | minor (0.x، breaking) |
|
||
| `@react-three/fiber` | `^8.18.0` | `^9.6.1` | **major** |
|
||
| `@react-three/drei` | `^9.122.0` | `^10.7.7` | **major** |
|
||
| `@react-three/postprocessing` | `^2.19.1` | `^3.0.4` | **major** |
|
||
| `@tanstack/react-query` | `^5.17.0` | `^5.101.0` | minor |
|
||
| `axios` | `^1.6.0` | `^1.17.0` | minor |
|
||
| `lucide-react` | `^1.7.0` | `^1.18.0` | minor |
|
||
| `react-hook-form` | `^7.49.0` | `^7.79.0` | minor |
|
||
| `react-toastify` | `^11.0.5` | `^11.1.0` | minor |
|
||
|
||
\* `tailwindcss` در بخش devDependencies است؛ اینجا برای خوانایی کنار بقیه آمد.
|
||
|
||
بدون تغییر: `clsx`, `lenis`.
|
||
|
||
## Frontend — `devDependencies`
|
||
|
||
| بسته | قبل | بعد |
|
||
|---|---|---|
|
||
| `@types/react` | `^18.2.0` | `^19.2.17` |
|
||
| `@types/react-dom` | `^18.2.0` | `^19.2.3` |
|
||
| `@types/three` | `^0.169.0` | `^0.184.1` |
|
||
| `@types/node` | `^20.11.0` | `^24.0.0` |
|
||
| `tailwindcss` | `^3.4.1` | `^4.3.1` |
|
||
| `eslint` | `^8.56.0` | `^9.0.0` |
|
||
| `eslint-config-next` | `14.1.0` | `16.2.9` |
|
||
| `postcss` | `^8.4.33` | `^8.5.15` |
|
||
| `typescript` | `^5.3.3` | `^6.0.3` |
|
||
| `@tailwindcss/postcss` | — | **`^4.3.1` (جدید)** |
|
||
| `autoprefixer` | `^10.4.17` | **حذف شد** (Tailwind 4 خودش vendor-prefix میزند) |
|
||
|
||
---
|
||
|
||
## تغییرات کدِ لازم برای migration
|
||
|
||
### Backend
|
||
|
||
- **`@kubernetes/client-node` 0.x → 1.x** (بزرگترین کار — ~۲۰۰+ نقطهی فراخوانی در ۶ فایل):
|
||
- همهی متدهای API از آرگومان ترتیبی به **یک object** تغییر کردند:
|
||
`readNamespacedPod(name, ns)` → `readNamespacedPod({ name, namespace })`.
|
||
- پاسخها دیگر در `{ body }` پیچیده نمیشوند و **مستقیم** برمیگردند: `res.body.items` → `res.items`.
|
||
- شکل خطا عوض شد: `err.statusCode` → **`err.code`**.
|
||
- Content-Type برای patchها با `k8s.setHeaderOptions(...)` (آرگومان دومِ متد) ست میشود.
|
||
- `kc.applyToRequest(opts)` → `kc.applyToHTTPSOptions(opts)`.
|
||
- فایلها: `kubernetes/kubernetes.service.ts`, `build/build.service.ts`, `clusters/clusters.service.ts`,
|
||
`clusters/cluster-tools.service.ts`, `kubernetes/elasticsearch.service.ts`, `kubernetes/registry.service.ts`.
|
||
- **تست رگرسیون:** `kubernetes/k8s-client-v1-migration.spec.ts` — شکل آرگومان object، unwrapِ پاسخ و تشخیص ۴۰۴ با `err.code`.
|
||
- **TypeORM 0.3 → 1.0:** آرایهی رشتهایِ `relations`/`select` دیگر پذیرفته نمیشود؛ به فرم object تبدیل شد
|
||
(`relations: ['user']` → `relations: { user: true }`) در ۹ سرویس.
|
||
- **`@nestjs/config` 3 → 4:** `ConfigService.get()` حالا `T | undefined` برمیگرداند؛ در `auth/strategies/jwt.strategy.ts`
|
||
از `getOrThrow<string>('jwt.secret')` استفاده شد (اگر secret نباشد همان boot کرش میکند).
|
||
- **TypeScript 5 → 6** (در `backend/tsconfig.json`):
|
||
- `strictPropertyInitialization: false` (TS6 آن را با `strictNullChecks` فعال میکند؛ entityهای TypeORM به آن وابستهاند).
|
||
- `ignoreDeprecations: "6.0"` (برای `baseUrl` که در TS7 حذف میشود — هنوز برای `tsconfig-paths` لازم است).
|
||
- `rootDir: "./src"` (الزام جدیدِ emit در TS6).
|
||
- `types: ["node", "jest", "multer"]` (TS6 دیگر همهی `@types/*` را خودکار include نمیکند؛ این پکیجها فقط ambient augmentation دارند).
|
||
|
||
### Frontend
|
||
|
||
- **Next 14 → 16:** `params`/`searchParams` حالا `Promise` هستند؛ با codemod رسمی
|
||
`npx @next/codemod next-async-request-api` اعمال شد (در `app/[lang]/layout.tsx` و موارد لازم).
|
||
- **TypeScript 6:** `target: "es5"` → `"ES2017"` در `frontend/tsconfig.json` (es5 در TS6 منسوخ شده).
|
||
- **Tailwind 3 → 4:**
|
||
- `postcss.config.js`: پلاگین `tailwindcss` + `autoprefixer` با **`@tailwindcss/postcss`** جایگزین شد.
|
||
- `src/app/globals.css`: سه دستورِ `@tailwind ...` با `@import 'tailwindcss';` + `@config '../../tailwind.config.ts';` جایگزین شد
|
||
(تا کانفیگِ JS موجود — رنگهای `primary` و فونتها — در v4 لود شود).
|
||
- `@apply`ـهایی که کلاسهای **سفارشی** را ترکیب میکردند (`@apply badge ...`، `@apply card ...`) بهصورت inline باز شدند
|
||
(v4 از ترکیب کلاس سفارشی در `@apply` پشتیبانی نمیکند).
|
||
|
||
### زیرساخت
|
||
|
||
- `backend/Dockerfile` و `frontend/Dockerfile`: پایه از `node:20-alpine` به **`node:24-alpine`** (تضمین `require(esm)` برای k8s client و هماهنگی با `@types/node@24`).
|
||
|
||
---
|
||
|
||
## نکات و کارهای باقیمانده
|
||
|
||
- **آسیبپذیریهای باقیماندهی audit:** backend چند مورد از طریق زنجیرهی transitive (`bull` → `uuid` قدیمی)؛ frontend ۲ مورد moderate. بدون breaking قابلرفع نیستند و مربوط به وابستگیهای غیرمستقیماند.
|
||
- **هشدار Next 16:** قرارداد فایل `middleware` به نفع `proxy` منسوخ اعلام شده (هنوز کار میکند). در ارتقای بعدی `middleware.ts` → `proxy.ts`.
|
||
- **تستِ از-پیش-شکسته:** `helm.service.spec.ts › chartPath` به propertyای اشاره میکند که در سرویس وجود ندارد؛ این پیش از این ارتقا هم fail میشد و ربطی به تغییرات اینجا ندارد.
|
||
- **اعتبارسنجی runtime:** چون کلاسترِ k8s واقعی در دسترس نبود، صحت typeها و buildها تأیید شده؛ پیش از پروداکشن، مسیرهای کنترلپلینِ k8s باید روی یک کلاسترِ تست اجرا شوند.
|