- 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
62 lines
1.6 KiB
JSON
62 lines
1.6 KiB
JSON
{
|
|
"name": "onlypets",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"scripts": {
|
|
"dev": "next dev",
|
|
"build": "next build",
|
|
"start": "next start",
|
|
"lint": "eslint"
|
|
},
|
|
"prisma": {
|
|
"seed": "npx tsx prisma/seed.ts"
|
|
},
|
|
"dependencies": {
|
|
"@aws-sdk/client-s3": "^3.1062.0",
|
|
"@aws-sdk/s3-request-presigner": "^3.1062.0",
|
|
"@base-ui/react": "^1.5.0",
|
|
"@clerk/nextjs": "^7.4.3",
|
|
"@prisma/adapter-pg": "^7.8.0",
|
|
"@prisma/client": "^7.8.0",
|
|
"@prisma/extension-accelerate": "^3.0.1",
|
|
"@supabase/supabase-js": "^2.107.0",
|
|
"@tanstack/react-query": "^5.101.0",
|
|
"@trpc/client": "^11.17.0",
|
|
"@trpc/server": "^11.17.0",
|
|
"@trpc/tanstack-react-query": "^11.17.0",
|
|
"@upstash/redis": "^1.38.0",
|
|
"class-variance-authority": "^0.7.1",
|
|
"client-only": "^0.0.1",
|
|
"clsx": "^2.1.1",
|
|
"lucide-react": "^1.17.0",
|
|
"next": "16.2.7",
|
|
"next-themes": "^0.4.6",
|
|
"pg": "^8.21.0",
|
|
"prisma": "^7.8.0",
|
|
"react": "19.2.4",
|
|
"react-dom": "19.2.4",
|
|
"server-only": "^0.0.1",
|
|
"shadcn": "^4.10.0",
|
|
"sonner": "^2.0.7",
|
|
"tailwind-merge": "^3.6.0",
|
|
"tw-animate-css": "^1.4.0",
|
|
"zod": "^4.4.3"
|
|
},
|
|
"devDependencies": {
|
|
"@tailwindcss/postcss": "^4",
|
|
"@types/node": "^20",
|
|
"@types/pg": "^8.20.0",
|
|
"@types/react": "^19",
|
|
"@types/react-dom": "^19",
|
|
"@vitejs/plugin-react": "^6.0.2",
|
|
"@vitest/coverage-v8": "^4.1.8",
|
|
"eslint": "^9",
|
|
"eslint-config-next": "16.2.7",
|
|
"jsdom": "^28.1.0",
|
|
"tailwindcss": "^4",
|
|
"tsx": "^4.22.4",
|
|
"typescript": "^6.0.3",
|
|
"vitest": "^4.1.8"
|
|
}
|
|
}
|