From 1f1153bf0d84013733166f1870bb9e027b2ea395 Mon Sep 17 00:00:00 2001 From: thxforall <113906780+thxforall@users.noreply.github.com> Date: Thu, 28 May 2026 19:47:44 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix(web):=20transpilePackages=20=EC=97=90?= =?UTF-8?q?=20@next/third-parties=20=EC=B6=94=EA=B0=80=20(Turbopack=20Verc?= =?UTF-8?q?el=20build=20=ED=9A=8C=EB=B3=B5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vercel build (dev/main/feature 전역) 가 \`Module not found: Can't resolve '@next/third-parties/google'\` 로 실패 중. Turbopack 의 subpath export 해석 회귀이며 vercel/next.js#58697 계열로 reported. \`transpilePackages\` 에 \`@next/third-parties\` 추가로 Turbopack 의 ESM resolution 우회. 로컬 \`next build\` 에서 검증 (Compiled successfully in 3.0min, @next/third-parties/google 더 이상 resolve 실패 안 함). ## Why this works \`transpilePackages\` 는 monorepo 의 workspace 가 아닌 node_modules 패키지를 대상으로도 동작, Next.js 가 해당 모듈을 SWC/Turbopack 으로 transpile 하면서 subpath export 를 정상 풀어낸다. ## Alternative considered - @next/third-parties pin (next 16.2.1 ↔ @next/third-parties 16.2.6 mismatch) → caret range 가 같지만 Bun 이 다르게 resolve. pin 은 lockfile 갱신 부담. - next 16.2.6 upgrade → minor 영향 범위 커서 보류. ## Related - vercel/next.js#58697 — @next/third-parties module not found - handoff session 4: dev/main/feature 전역 Vercel fail 추적 Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/web/next.config.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/web/next.config.js b/packages/web/next.config.js index 96c4a85a..6ac50d0c 100644 --- a/packages/web/next.config.js +++ b/packages/web/next.config.js @@ -4,7 +4,9 @@ const { withSentryConfig } = require("@sentry/nextjs"); const nextConfig = { reactStrictMode: true, // Transpile shared package from monorepo - transpilePackages: ["@decoded/shared"], + // `@next/third-parties` 는 Turbopack 의 subpath export 해석 회귀로 추가 + // (`@next/third-parties/google` resolve 실패 — vercel/next.js#58697 계열). + transpilePackages: ["@decoded/shared", "@next/third-parties"], images: { localPatterns: [{ pathname: "/**" }], // Direct-optimization allowlist — must stay in sync with From 1c3ea4a3d76d12c79648f6c1f834a3d10b6a3770 Mon Sep 17 00:00:00 2001 From: thxforall <113906780+thxforall@users.noreply.github.com> Date: Thu, 28 May 2026 20:01:32 +0900 Subject: [PATCH 2/4] fix(content-studio): remove dead useResearchInCopy key from local video script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vercel build TS step fail (\`Object literal may only specify known properties, and 'useResearchInCopy' does not exist in type 'BuildShortFormPlanInput'\`) 해소. \`buildShortFormPlan\` 의 \`BuildShortFormPlanInput\` type 은 \`{packet, variants, platform, durationSeconds}\` 4개만 받는다. \`useResearchInCopy\` 는 어디서도 read 되지 않는 dead key — #592 작업 중 남은 leftover. 제거해도 동작 변화 없음. 본 PR (transpilePackages 추가) 와 함께 적용해야 Vercel build green 으로 전환. Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/web/scripts/content-studio-video-local.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web/scripts/content-studio-video-local.ts b/packages/web/scripts/content-studio-video-local.ts index 54285b5c..e7ed2499 100644 --- a/packages/web/scripts/content-studio-video-local.ts +++ b/packages/web/scripts/content-studio-video-local.ts @@ -556,7 +556,6 @@ async function main() { platform: platform as ShortFormPlatform, durationSeconds, variants: [], - useResearchInCopy: false, }); const scenes = plan.scenes.filter( (scene) => !selectedSceneIds || selectedSceneIds.has(scene.id) From e0944633b93e09f90604e50fa56cac9eb7035f1d Mon Sep 17 00:00:00 2001 From: thxforall <113906780+thxforall@users.noreply.github.com> Date: Thu, 28 May 2026 20:18:27 +0900 Subject: [PATCH 3/4] ci: trigger fresh Vercel build (bust cache) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이전 deployment 가 'Restored build cache from previous deployment' 로 진행되어 구 dependency state 가 잔존했을 가능성. empty commit 으로 fresh build 트리거. From ebba59eb477b8ace4631832a2371da9dcab6f159 Mon Sep 17 00:00:00 2001 From: thxforall <113906780+thxforall@users.noreply.github.com> Date: Thu, 28 May 2026 20:22:41 +0900 Subject: [PATCH 4/4] fix(api): cap maxDuration at 60s for video routes (Vercel Hobby limit) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vercel Hobby plan 의 Serverless Function maxDuration 제한 (1-60s) 위반으로 배포 실패: \`\`\` Builder returned invalid maxDuration value for Serverless Function \"api/v1/content/assets/video-jobs/[jobId]/compose\". Serverless Functions must have a maxDuration between 1 and 60 for plan hobby. \`\`\` 수정: - \`api/v1/content/assets/video-jobs/[jobId]/compose/route.ts\`: 600 → 60 - \`api/v1/content/assets/videos/route.ts\`: 300 → 60 긴 compose/video 작업은 background job 패턴 (\`/poll\` endpoint 와 함께) 으로 처리해야 함. Vercel Pro 업그레이드 시 원래 값 복원 가능 (Pro: 800s 까지). \#592 Video Pipeline 도입 시 누락된 Hobby 호환성 제약. Co-Authored-By: Claude Opus 4.7 (1M context) --- .omc/project-memory.json | 12 ++++++------ .../assets/video-jobs/[jobId]/compose/route.ts | 4 +++- .../web/app/api/v1/content/assets/videos/route.ts | 3 ++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.omc/project-memory.json b/.omc/project-memory.json index d8a089ab..052d3caa 100644 --- a/.omc/project-memory.json +++ b/.omc/project-memory.json @@ -257,6 +257,12 @@ "lastAccessed": 1776433904397, "type": "file" }, + { + "path": "packages/web/next.config.js", + "accessCount": 4, + "lastAccessed": 1779965242978, + "type": "file" + }, { "path": "packages/web/lib/image-loader.ts", "accessCount": 3, @@ -287,12 +293,6 @@ "lastAccessed": 1776391802453, "type": "file" }, - { - "path": "packages/web/next.config.js", - "accessCount": 2, - "lastAccessed": 1776432841858, - "type": "file" - }, { "path": "scripts/start-issue.sh", "accessCount": 1, diff --git a/packages/web/app/api/v1/content/assets/video-jobs/[jobId]/compose/route.ts b/packages/web/app/api/v1/content/assets/video-jobs/[jobId]/compose/route.ts index 371258ec..c34949dc 100644 --- a/packages/web/app/api/v1/content/assets/video-jobs/[jobId]/compose/route.ts +++ b/packages/web/app/api/v1/content/assets/video-jobs/[jobId]/compose/route.ts @@ -18,7 +18,9 @@ async function requireAdmin() { return null; } -export const maxDuration = 600; +// Vercel Hobby plan: maxDuration 1-60s 제한. 긴 compose 작업은 background +// job 패턴 (poll endpoint 와 함께) 으로 처리. Pro plan 업그레이드 시 600 복원 가능. +export const maxDuration = 60; export async function POST( request: NextRequest, diff --git a/packages/web/app/api/v1/content/assets/videos/route.ts b/packages/web/app/api/v1/content/assets/videos/route.ts index fbd6f42d..1913d4d3 100644 --- a/packages/web/app/api/v1/content/assets/videos/route.ts +++ b/packages/web/app/api/v1/content/assets/videos/route.ts @@ -22,7 +22,8 @@ async function requireAdmin() { return null; } -export const maxDuration = 300; +// Vercel Hobby plan: maxDuration 1-60s 제한. Pro plan 업그레이드 시 300 복원 가능. +export const maxDuration = 60; export async function POST(request: NextRequest) { const adminError = await requireAdmin();