// Auto-generated from src/ai-service/skills/system/third-party-migration/v0.md
// Do not edit directly - edit the .md file instead
export const content = `# v0-specific mapping

This is a per-platform reference loaded from \`SKILL.md\`. The framework (target layout, universal mapping, non-negotiables, workflow, code-emission rules) lives there. This file documents only what is specific to a v0 source.

> v0 (Vercel) emits a Next.js App Router project the vast majority of the time. The Superblocks 3.0 fullstack template is **Vite + react-router**, not Next.js, so every page port involves translating Next.js primitives (server components, file-system routing, \`next/*\` imports) into the Vite/react-router shape. Treat that translation as the core of the migration; the data-mapping side is usually thin because v0 sources rarely have real backends.

## Where the source lives

Definitive marker: \`app/layout.tsx\` exports a \`metadata\` object with \`generator: 'v0.app'\`. If you find that, it is a v0 export.

Strong supporting signals:

- \`app/\` directory at the repo root containing \`page.tsx\` / \`layout.tsx\`, plus \`next.config.{js,mjs,ts}\` and \`next\` listed as a dependency in \`package.json\`.
- \`components.json\` at the repo root (shadcn CLI config) with \`"style": "new-york"\` and \`"iconLibrary": "lucide"\`.
- \`components/ui/\` with shadcn primitives and a heavy roster of \`@radix-ui/react-*\` packages.
- \`next.config.mjs\` with \`images: { unoptimized: true }\` and often \`typescript: { ignoreBuildErrors: true }\` (v0 escape hatches; surface both as warnings since they hide real issues).
- Frequent imports from \`next/link\`, \`next/navigation\`, \`next/image\`, \`next/font\`, and a \`<Analytics />\` from \`@vercel/analytics/next\` in the layout.
- Standard placeholder assets in \`public/\`: \`placeholder.svg\`, \`placeholder.jpg\`, \`placeholder-logo.{svg,png}\`, \`placeholder-user.jpg\`. Source code often references these.
- A \`styles/globals.css\` AND an \`app/globals.css\` may both exist. The active one is whichever the layout imports (typically \`app/globals.css\`); the other is dead code from the shadcn scaffold. Surface this in discovery so the user knows.

If the user gave a path, use it. Otherwise look for the markers above in the working tree. If ambiguous (for example the source is plain Next.js with no \`generator: 'v0.app'\` and no \`components.json\`), ask before assuming v0 conventions, since unrelated Next.js apps can have their own non-trivial server logic that the v0 mapping below underestimates.

## Typical shape (hints, not rules)

Use these as starting points; re-verify against the actual source tree on every migration.

- **Frontend**: Next.js 14/15 App Router + React 18/19 + Tailwind (often v4 with \`@import 'tailwindcss'\` and OKLCH theme tokens in \`app/globals.css\`) + shadcn/ui (under \`components/ui/\`) + \`lucide-react\`. Pages live at \`app/<segment>/page.tsx\`; layouts at \`app/<segment>/layout.tsx\`. Route groups use \`(group-name)/\` directories. Dynamic segments use \`[param]\` directories. Forms via \`react-hook-form\` + \`zod\` are common but not universal.
- **Theming**: \`next-themes\` with a \`<ThemeProvider>\` in \`app/layout.tsx\` is the default v0 dark-mode wiring. Translate to a custom provider or drop and pin a theme; \`next-themes\` itself does not work outside Next.
- **Fonts**: \`next/font/google\` loading Geist + Geist_Mono is the default v0 font stack (with CSS variables \`--font-geist-sans\` / \`--font-geist-mono\`). Re-load via \`@import\` from Google Fonts in \`client/index.css\` and re-bind the variables in Tailwind v4 tokens.
- **Analytics**: \`<Analytics />\` from \`@vercel/analytics/next\` in the root layout is boilerplate. Drop entirely — there is no Superblocks equivalent and the component is Vercel-platform-bound.
- **Backend (when present)** — pick whichever the source actually uses:
  - **Server Actions**: functions or files with \`"use server"\`, often in \`app/actions.ts\` or co-located with the page. Called from client components via form actions or direct invocation.
  - **API Routes**: \`app/api/<name>/route.ts\` exporting \`GET\`, \`POST\`, etc. handlers.
  - **Server Component data fetching**: \`async function Page()\` with inline \`fetch(...)\` or DB calls. The result is rendered server-side and shipped as HTML on first load.
  - **Third-party APIs called from the client** (Stripe, OpenAI, AI SDK) with secrets that should never have been in \`NEXT_PUBLIC_*\`.
  - **No backend at all**: pure UI app with mocked data or \`localStorage\`. The framework's "Don't fabricate a backend" rule applies; the migrated app stays frontend-only.
- **Auth**: occasionally a \`middleware.ts\` with NextAuth / Clerk / hand-rolled session checks. Frequently absent in v0-only outputs.
- **Storage**: occasionally \`@vercel/blob\` or third-party uploads. Often absent.
- **Streaming / AI**: AI SDK (\`ai\`, \`@ai-sdk/openai\`) with streamed responses sometimes shows up in v0 outputs. **Superblocks has no streaming-response equivalent in this template** — flag and degrade to one-shot calls; do not silently drop.

## Discovery checklist

In addition to the framework's discovery requirements, for a v0 source enumerate:

- Every page (\`app/**/page.tsx\`) and its dynamic-segment params.
- Every layout (\`app/**/layout.tsx\`) and what it provides (theme provider, header, sidebar, fonts).
- Every Server Action (\`"use server"\` functions or files), grouped by what they touch.
- Every API Route (\`app/api/**/route.ts\`), grouped by HTTP method.
- Every Server Component that fetches data inline (look for \`async function\` page/layout exports calling \`fetch\`, ORMs, or DB clients).
- Every \`next/*\` import in use (\`next/link\`, \`next/navigation\`, \`next/image\`, \`next/font\`, \`next/headers\`, \`next/cookies\`, \`next/cache\`).
- Every external HTTP call and the API it targets (in client components, Server Actions, and Server Components).
- Every env var read (\`process.env.*\`, \`import.meta.env.*\`), separated into "credentials/secrets" (move to integrations) and "config" (\`ctx.env\`).
- Every middleware (\`middleware.ts\`) — usually drops, but capture what it was doing so the equivalent can be implemented at the API layer if needed.
- Theme port surface: \`tailwind.config.{js,ts}\`, \`app/globals.css\`, font setup via \`next/font\`, custom CSS modules.

If the discovery summary doesn't tell you what every API will look like and how every page changes shape, you haven't discovered enough.

## Core mapping

- **Each page (\`app/.../page.tsx\`) → one Superblocks page** at \`client/pages/<Name>/index.tsx\`, wired into \`client/router.tsx\`. Route groups (\`(name)/\`) collapse into nested routes; dynamic segments (\`[id]/\`) become \`:id\` params under react-router v7.
- **Each Server Component that fetches data inline → one Superblocks API + a client component**. The page becomes a normal client component that calls \`useApiData("<ApiName>")\`. The inline \`fetch\` / DB call moves into \`server/apis/<ApiName>/api.ts\`. There is no server-rendered first paint in this template; the page renders with a loading state and hydrates from the API.
- **Each Server Action (\`"use server"\` function) → one Superblocks API** at \`server/apis/<ActionName>/api.ts\`, called from the client via \`useApi("<ActionName>")\` (mutations) or \`executeApi\`. Form-action wiring (\`<form action={...}>\`) becomes a normal \`onSubmit\` handler that calls the API. \`revalidatePath\` / \`revalidateTag\` calls drop; refetch via the returned hook's invalidation pattern instead.
- **Each API Route (\`app/api/<name>/route.ts\`) → one Superblocks API** at \`server/apis/<NameInPascalCase>/api.ts\`. Route handlers exporting \`GET\`, \`POST\`, etc. that share a path collapse into one \`api()\` keyed by method on the input schema, or split into separate APIs per method. Pick one shape and stay consistent. \`Request\` / \`Response\` / \`NextResponse\` primitives drop entirely; the platform handles HTTP.
- **Each external HTTP call → integration**. \`fetch("https://api.openai.com/...")\` becomes a declared integration plus \`apiRequest(...)\`. Secrets from \`process.env\`, \`NEXT_PUBLIC_*\`, hardcoded keys, or AI SDK provider configs move into the integration definition. A \`NEXT_PUBLIC_OPENAI_API_KEY\` on the client side is also a security finding worth surfacing in the migration summary.
- **DB clients** (Drizzle, Prisma, \`@vercel/postgres\`, \`@neondatabase/serverless\`, \`pg\`) → declare in \`integrations: { db: postgres(DB_INTEGRATION_ID) }\` and call \`ctx.integrations.db.query/execute(...)\` with parameterized SQL. Read schema from any included migration files; do not run them against the target integration without asking.
- **\`next/link\`** → \`import { Link } from "react-router"\` (v7). The \`href\` prop becomes \`to\`.
- **\`next/navigation\`** → react-router v7 hooks: \`useRouter()\` becomes \`useNavigate()\`, \`usePathname()\` becomes \`useLocation().pathname\`, \`useSearchParams()\` stays \`useSearchParams()\` from \`react-router\` (similar API but not identical, verify call sites).
- **\`next/image\`** → standard \`<img>\` with the same \`src\`/\`alt\`. Drop the \`width\`/\`height\`/\`priority\` props or convert to inline styles. If the source relied on Next's image optimization (remote loaders, blur placeholders), flag as a \`failed\` item with \`failureReason: "next/image optimization on <usage> has no Superblocks equivalent in this template"\`.
- **\`next/font/google\`** → **never just delete the import**. The font has to be re-loaded somewhere or it disappears from the migrated app and everything renders in the browser fallback. Three required steps; all three are mandatory:
  - **(a) Load the font.** Pick one shape and stay consistent within the migration:
    1. **CDN \`@import\` (default; zero new deps).** At the top of \`client/index.css\`: \`@import url('https://fonts.googleapis.com/css2?family=<Family>:wght@<weights>&display=swap');\`. Bring over both the sans and mono family the source used.
    2. **Self-hosted via npm.** For Geist specifically: \`pnpm add geist\`, then \`import 'geist/font/sans'; import 'geist/font/mono';\` from \`client/main.tsx\` (it injects \`@font-face\` and exposes \`--font-geist-sans\` / \`--font-geist-mono\`). For other Google fonts: \`pnpm add @fontsource-variable/<family>\` and \`import '@fontsource-variable/<family>';\`.
  - **(b) Bind it in \`@theme\`.** The starter \`client/index.css\` ships with no \`--font-sans\` token, so even after loading the font you must add \`@theme { --font-sans: '<Family>', ui-sans-serif, system-ui, sans-serif; --font-mono: '<MonoFamily>', ui-monospace, monospace; }\` (or a \`var(--font-geist-sans)\` reference for the self-hosted Geist case). Without this, Tailwind's \`font-sans\` keeps using the browser default.
  - **(c) Drop the source's \`next/font\` import and the \`className={font.variable}\` wiring** on \`<html>\` / \`<body>\` — the Tailwind token from (b) carries the variable forward instead.

  The most common port failure is silently dropping (a): the agent removes the \`next/font\` import as part of "drop Next-isms" and never adds a replacement, so the migrated app renders in system fonts. (b) without (a) is just as bad. **Verify by inspecting a heading in DevTools and confirming \`font-family\` resolves to the source's family, not \`ui-sans-serif\`/system fallback.** If a font is intentionally not carried over, surface it as a \`failed\` item with a reason; do not drop silently.

- **\`next/font/local\`** → copy the font files to \`client/public/fonts/\`, write matching \`@font-face\` blocks in \`client/index.css\`, and bind the family name in \`@theme\`. Preserve the original \`font-display\`, weight, and style.
- **\`app/layout.tsx\`** → fold into \`client/App.tsx\` (the root shell with \`<AppProvider>\` + \`<Outlet />\`) or into specific page wrappers, depending on what each layout provided. Theme providers, font loaders, and metadata setters from layouts collapse into the App shell or \`client/index.css\`. The \`<html>\`/\`<body>\` shell drops; the platform owns it.
- **\`app/loading.tsx\`** → component-level loading state in the page, driven by \`useApiData\`'s loading boolean. There is no implicit Suspense boundary in this template.
- **\`app/error.tsx\`** → react-router v7 \`errorElement\` on the route, or a try/catch around the API hook with a fallback render.
- **\`metadata\` exports / \`generateMetadata\`** → drop, or set \`document.title\` via \`useEffect\` if the page title matters. Open Graph / Twitter card metadata has no equivalent here.
- **\`middleware.ts\`** → drop. If it was enforcing auth, the equivalent enforcement happens server-side in each \`api()\` via \`ctx.user\`. If it was rewriting URLs, surface to the user — Superblocks has no URL-rewriting layer.
- **\`"use client"\` / \`"use server"\` directives** → drop. Every component in the Superblocks template is a client component; every server-side function lives in \`server/apis/\`. There is no RSC boundary to mark.
- **\`next-themes\`** → translate to a small custom provider that toggles a \`class="dark"\` on \`document.documentElement\` and persists to \`localStorage\`, or drop entirely and pin the theme. The \`next-themes\` package depends on Next-specific hydration behavior and should not be carried over as-is. Preserve the source's CSS variable scheme (\`:root\` / \`.dark\` blocks in \`globals.css\`) — only the JS toggle changes.
- **\`@vercel/analytics\`** → drop. The \`<Analytics />\` component and \`track()\` helper are bound to the Vercel platform and have no equivalent here. Note in the migration summary if the source relied on it.

## Ask-before-guessing — v0 specifics

- "The source uses Server Actions / API Routes calling \`<DB client>\` against \`<DSN env var>\`. I'll bind to a Postgres integration; which one, or do you want to create a new one?"
- "I see external HTTP calls to \`<host>\` with credentials in \`<env var>\`. Bind to an integration of type \`<kind>\`?"
- "I see \`<feature>\` (streaming AI responses, edge runtime, ISR, etc.) which has no equivalent in this template. Drop, degrade, or stop and let you decide?"
- "I see Server Components fetching data inline. The migrated app cannot server-render; the page will hydrate from the API with a loading state. Is that acceptable, or do you want a particular skeleton/loading shape?"
- "The source has a \`middleware.ts\` doing \`<auth/redirect/rewrite>\`. I'll drop it and enforce equivalent rules in each API via \`ctx.user\`. Is that the right user-claim mapping?"

## Page port — what changes vs. what doesn't

For each v0 page, only these change:

- **Data hooks**: Server Component inline fetch / Server Action calls / API Route fetches → \`useApi\` / \`useApiData\`.
- **Auth touchpoints**: NextAuth / Clerk / \`middleware.ts\` checks → platform-managed (drop the provider; consume \`ctx.user\` server-side).
- **Router primitives**: \`next/link\`, \`next/navigation\`, file-system routing → react-router v7 (\`Link\`, \`useNavigate\`, \`useLocation\`, explicit route definitions in \`client/router.tsx\`).
- **Asset primitives**: \`next/image\` → \`<img>\`, \`next/font\` → CSS-loaded fonts.
- **Directives**: \`"use client"\` / \`"use server"\` removed.

Everything else (JSX structure, Tailwind classes, shadcn variants, custom CSS, theme tokens, layout containers) transfers unchanged. If the diff goes beyond data + auth + routing + asset/font primitives + directive removal, you are over-editing.

## Done — v0 specifics

In the final report, additionally surface:

- Any unsupported features that became \`failed\` items (streaming AI responses, server-side rendering, ISR, \`next/image\` optimization, edge runtime, route rewrites, etc.).
- Any \`NEXT_PUBLIC_*\` secrets found on the client side (these should be rotated even after migration).
- The list of \`next/*\` imports that were translated, so the user can spot-check them in the migrated tree.
`;
//# sourceMappingURL=v0.generated.js.map