Files
petfeed/src/app/layout.tsx
T
admin e0214ea0f8 feat(01-01): wire Clerk proxy.ts, Prisma 7 schema + singleton, tRPC stack, R2 client, ActivePetContext
- Create proxy.ts at repo root with clerkMiddleware + createRouteMatcher (public allowlist: sign-up, log-in, forgot-password, reset-password, verify-email)
- Create prisma/schema.prisma: Owner, Species, Breed, Pet models with ownership index and FK constraints
- Create prisma.config.ts with Prisma 7 defineConfig (datasource url via env)
- Create src/lib/prisma.ts: Prisma 7 singleton using @prisma/adapter-pg for local dev, withAccelerate() for Prisma Accelerate on Vercel
- Create src/lib/r2.ts (server-only): S3Client + getPresignedUploadUrl with contentType enforcement and 300s expiry
- Create src/lib/auth.ts: getOwnerId() Clerk auth wrapper
- Create src/trpc/init.ts: createTRPCContext, router, publicProcedure, protectedProcedure (throws UNAUTHORIZED)
- Create src/trpc/routers/pets.ts: pets.create (upserts Owner, creates Pet with ownerId=ctx.userId), pets.list (scoped), pets.byId (ownership-asserted)
- Create src/trpc/routers/_app.ts: appRouter + AppRouter type export
- Create src/trpc/query-client.ts, server.ts (RSC caller), client.tsx (TRPCReactProvider + useTRPC)
- Create src/app/api/trpc/[trpc]/route.ts: tRPC fetch handler (GET + POST)
- Create src/context/ActivePetContext.tsx + src/hooks/useActivePet.ts: localStorage-backed active pet context
- Create prisma/seed.ts: seeds Dog/Cat/Bird species idempotently via upsert
- Update src/app/layout.tsx: wrap children in ClerkProvider (orange primary), TRPCReactProvider, ActivePetProvider, Toaster
- Install @prisma/adapter-pg + pg for Prisma 7 local dev (Rule 2: required for Prisma 7 engine compatibility)
- [Rule 1 - Bug] Prisma 7 no longer supports url/directUrl in schema.prisma; moved to prisma.config.ts with defineConfig
2026-06-05 19:18:16 +02:00

47 lines
1.2 KiB
TypeScript

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { ClerkProvider } from "@clerk/nextjs";
import { TRPCReactProvider } from "@/trpc/client";
import { ActivePetProvider } from "@/context/ActivePetContext";
import { Toaster } from "@/components/ui/sonner";
import "./globals.css";
const inter = Inter({
variable: "--font-sans",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "OnlyPets",
description: "The social platform where pets are the stars.",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<ClerkProvider
appearance={{
variables: {
colorPrimary: "#F97316",
colorBackground: "#FAFAFA",
colorText: "#09090B",
},
}}
>
<html lang="en" className={`${inter.variable} h-full antialiased font-sans`}>
<body className="min-h-full flex flex-col">
<TRPCReactProvider>
<ActivePetProvider>
{children}
<Toaster />
</ActivePetProvider>
</TRPCReactProvider>
</body>
</html>
</ClerkProvider>
);
}