5.3 KiB
Task 03: Next.js Major Upgrade Report (Eliminating High Advisories)
Date: 2026-08-21
Base Commit SHA: 6f3fd44333cbb200d82efa665d191f660b100144
Status: COMPLETED / PASS
Assigned Agent: Antigravity (Implementation Orchestrator)
1. Executive Summary
Выполнен мажорный апгрейд инфраструктуры Next.js и React:
next:14.2.15→16.3.2react&react-dom:18.3.1→19.2.8@types/react&@types/react-dom:^19.2.18/^19.2.4eslint&eslint-config-next:^9.20.0/^16.3.2postcss:^8.5.26
В результате npm audit --omit=dev возвращает 0 vulnerabilities (устранены уязвимости next GHSA-955p-x3mx-jcvp и postcss GHSA-6g55-p6wh-862q, GHSA-fxqj-rqcc-2cmp, GHSA-r28c-9q8g-f849, GHSA-qx2v-qp2m-jg93).
Все 300 тестов проходят без изменений бизнес-логики и криптографических инвариантов.
2. Initial vs Final Audit Output
Initial npm audit --omit=dev:
2 high severity vulnerabilities
- next 9.3.4-canary.0 - 16.3.0-preview.10 (GHSA-955p-x3mx-jcvp)
- postcss <=8.5.22 (GHSA-6g55-p6wh-862q, GHSA-fxqj-rqcc-2cmp, GHSA-r28c-9q8g-f849, GHSA-qx2v-qp2m-jg93)
Final npm audit --omit=dev:
found 0 vulnerabilities
3. Breaking Changes & Migration Details
1. App Router Dynamic Route Parameters (Promise<params>)
В Next.js 15+ аргумент params в Route Handlers передаётся как Promise.
Обновлены все 5 динамических эндпоинтов:
src/app/api/giveaways/[id]/route.tssrc/app/api/giveaways/[id]/draw/route.tssrc/app/api/giveaways/[id]/participants/route.tssrc/app/api/giveaways/[id]/snapshot/route.tssrc/app/api/giveaways/[id]/verify/route.ts
Сигнатура параметров типизирована как { params: Promise<{ id: string }> | { id: string } } и распаковывается через const { id } = await params;, что обеспечивает 100% совместимость.
2. NextRequest.ip Type Definition
В Next.js 15+ поле ip удалено из интерфейса NextRequest.
В src/lib/client-ip.ts реализован безопасный доступ к сокетному IP: (req as unknown as { ip?: string }).ip.
3. Flat Config для ESLint 9 (eslint.config.mjs)
Next.js 16 и ESLint 9 перешли на плоскую конфигурацию (flat config).
Создан файл eslint.config.mjs, экспортирующий массив nextConfig из eslint-config-next. Скрипт lint в package.json переведён на eslint ..
4. React 19 Strict Hook Rules (react-hooks/set-state-in-effect)
В src/app/page.tsx устранён синхронный вызов setLoading(true) при инициализации хука useEffect.
4. Modified Files
| File | Type | Description |
|---|---|---|
package.json |
Dependencies | Обновлены версии next, react, react-dom, eslint, eslint-config-next, postcss. Скрипт "lint": "eslint .". |
package-lock.json |
Lockfile | Обновлены зависимости и транзитивные деревья. |
eslint.config.mjs |
Config (NEW) | Конфигурация ESLint 9 Flat Config для Next.js 16. |
tsconfig.json |
Config | Обновлён Next.js (jsx: react-jsx, .next/dev/types/**/*.ts). |
src/lib/client-ip.ts |
Infrastructure | Безопасный доступ к directIp для Next.js 16. |
src/app/api/giveaways/[id]/route.ts |
API Route | Поддержка Promise<params>. |
src/app/api/giveaways/[id]/draw/route.ts |
API Route | Поддержка Promise<params>. |
src/app/api/giveaways/[id]/participants/route.ts |
API Route | Поддержка Promise<params>. |
src/app/api/giveaways/[id]/snapshot/route.ts |
API Route | Поддержка Promise<params>. |
src/app/api/giveaways/[id]/verify/route.ts |
API Route | Поддержка Promise<params>. |
src/app/page.tsx |
UI | Соблюдение правил React 19 set-state-in-effect. |
5. Verification Evidence & Test Gate
Фактически выполненные команды:
npx prisma generate -> EXIT 0 (Prisma Client v5.22.0)
npx tsc --noEmit -> EXIT 0 (Clean TypeScript check, 0 errors)
npm test -> EXIT 0 (51 test files, 300 tests passed, 0 failed)
npm run lint -> EXIT 0 (0 errors, 6 warnings on no-img-element)
npm run build -> EXIT 0 (Compiled with Turbopack, all 15 routes generated)
npm audit --omit=dev -> EXIT 0 (found 0 vulnerabilities)
6. Core Invariants & Security
- Randomizer / Audit Proof Invariants: Алгоритмы
HMAC_SHA256_FY_V1,executeDeterministicDrawV1,verifyDrawResultсохранены без изменений. - Fail-Closed Authorization: Сохранены все auth-guards, ownership checks, PKCE S256 и CSRF валидация.
- Dependencies:
prisma/@prisma/clientнамеренно не обновлялись в этой задаче в соответствии со Scope (выделено в отдельное запланированное обновление).