chore(deps): upgrade all dependencies to latest stable
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>
This commit is contained in:
@@ -14,23 +14,29 @@ export function generateStaticParams() {
|
||||
return locales.map((lang) => ({ lang }));
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: { lang: string };
|
||||
}): Promise<Metadata> {
|
||||
export async function generateMetadata(
|
||||
props: {
|
||||
params: Promise<{ lang: string }>;
|
||||
}
|
||||
): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
if (!isLocale(params.lang)) return {};
|
||||
const dict = await getDictionary(params.lang);
|
||||
return { title: dict.meta.title, description: dict.meta.description };
|
||||
}
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
params,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
params: { lang: string };
|
||||
}) {
|
||||
export default async function RootLayout(
|
||||
props: {
|
||||
children: React.ReactNode;
|
||||
params: Promise<{ lang: string }>;
|
||||
}
|
||||
) {
|
||||
const params = await props.params;
|
||||
|
||||
const {
|
||||
children
|
||||
} = props;
|
||||
|
||||
if (!isLocale(params.lang)) notFound();
|
||||
const locale: Locale = params.lang;
|
||||
const dict = await getDictionary(locale);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import 'tailwindcss';
|
||||
@config '../../tailwind.config.ts';
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
@@ -82,19 +81,20 @@
|
||||
transition-shadow duration-200;
|
||||
}
|
||||
.card-hover {
|
||||
@apply card hover:shadow-md hover:border-gray-300;
|
||||
@apply bg-white rounded-2xl shadow-sm border border-gray-200/80 p-6
|
||||
transition-shadow duration-200 hover:shadow-md hover:border-gray-300;
|
||||
}
|
||||
|
||||
/* ─── Badges ──────────────────────────────────────────── */
|
||||
.badge {
|
||||
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold;
|
||||
}
|
||||
.badge-green { @apply badge bg-emerald-100 text-emerald-700; }
|
||||
.badge-red { @apply badge bg-red-100 text-red-700; }
|
||||
.badge-blue { @apply badge bg-blue-100 text-blue-700; }
|
||||
.badge-yellow { @apply badge bg-amber-100 text-amber-700; }
|
||||
.badge-gray { @apply badge bg-gray-100 text-gray-600; }
|
||||
.badge-purple { @apply badge bg-purple-100 text-purple-700; }
|
||||
.badge-green { @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold bg-emerald-100 text-emerald-700; }
|
||||
.badge-red { @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold bg-red-100 text-red-700; }
|
||||
.badge-blue { @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold bg-blue-100 text-blue-700; }
|
||||
.badge-yellow { @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold bg-amber-100 text-amber-700; }
|
||||
.badge-gray { @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold bg-gray-100 text-gray-600; }
|
||||
.badge-purple { @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold bg-purple-100 text-purple-700; }
|
||||
|
||||
/* ─── Stat card ──────────────────────────────────────── */
|
||||
.stat-card {
|
||||
|
||||
Reference in New Issue
Block a user