The Archive (Next.js + tRPC + Drizzle)
AI coding assistant guidance for a Next.js app router project using tRPC, Drizzle ORM (SQLite), and NextAuth.
Overview
This repository is a Next.js (app router) project with tRPC on the server, Drizzle ORM (SQLite) for persistence, and NextAuth for authentication. This skill provides focused, actionable guidance to help you be productive quickly.
Architecture
**Framework:** Next.js (app directory)
Entry pages live under `src/app/`Logged-in pages are under `src/app/(logged in)/`**API Layer:** tRPC routers in `src/trpc/routers/*`
Top-level router: `src/trpc/routers/_app.ts`Mounted by server caller in `src/trpc/server.tsx`**Database:** Drizzle ORM with SQLite
Schema: `src/lib/db/schema.ts`Migrations: `drizzle/` folderOn-disk DB: `database/archive.db`**Auth:** NextAuth
Configuration: `src/auth.ts`Drizzle adapter and provider config: `src/auth.config.ts`Step-by-Step Instructions
1. Understand the Big Picture
Before making changes:
Entry pages: `src/app/`Authenticated pages: `src/app/(logged in)/`tRPC routers: `src/trpc/routers/*`DB schema: `src/lib/db/schema.ts`Auth config: `src/auth.ts` and `src/auth.config.ts`2. Developer Workflows
**Local development:**
```bash
pnpm dev
```
**Build production:**
```bash
pnpm build
```
**Start production server:**
```bash
pnpm start
```
**Database migrations:**
```bash
pnpm generate # Generate schema changes
pnpm migrate # Apply migrations
```
3. Project Conventions
**tRPC Context:**
Context creation: `src/trpc/init.ts` exports `createTRPCContext` which calls `auth()`Use `protectedProcedure` for authenticated endpointsUse `adminProcedure` for admin-only endpoints**Server Caller / Prefetching:**
Server helpers: `src/trpc/server.tsx` provides `trpc`, `caller`, and helpers `prefetch`/`HydrateClient`Use `caller` for server-side operations in server components**Database Definitions:**
Types exported from `src/lib/db/schema.ts` (e.g., `Work`, `NewWork`, `PenName`)Migrations live in `drizzle/` and are applied automatically by `src/lib/db/schema.ts` at startup**IMPORTANT:** Do not manually create migrations; use `pnpm generate` instead**Auth/Session Shape:**
NextAuth stores user ID in session at `session.user.id` (see `src/auth.ts` callbacks)Authenticated contexts expect `ctx.session.user.id` to exist4. Integration Points & Side Effects
**Migrations:**
`src/lib/db/schema.ts` will create the `database` directory and run migrations automatically when the DB doesn't existAvoid deleting migrations; add new SQL files to `drizzle/` and run `pnpm migrate`**Environment Variables:**
`OIDC_*` env vars configure the OIDC provider in `src/auth.config.ts``DB_LOG`, `DB_MIGRATE`, and `DB_URI` influence DB migration and logging behavior**tRPC + React Query:**
Uses `@trpc/tanstack-react-query` with cache helpersMaintain query keys and use `trpc.*.queryOptions()` when prefetching5. Common Edit Patterns
**UI/Styling:**
Do not overload elements with complex Tailwind classes; keep structure simpleRely on existing shadcn/ui components (in `src/components/ui`) whenever possible**Add a tRPC Endpoint:**
1. Create a router in `src/trpc/routers/`
2. Export it
3. Add it to `src/trpc/routers/_app.ts`
4. Use `protectedProcedure.input(z.object(...)).mutation(...)` for protected routes
5. Access DB via `ctx` (see `src/trpc/init.ts` for context shape)
Example:
```typescript
protectedProcedure
.input(z.object({ pennameid: z.string() }))
.mutation(async ({ input, ctx }) => {
// Your logic here
})
```
**Add a DB Column/Table:**
1. Add to `src/lib/db/schema.ts`
2. **IMPORTANT:** Batch all schema changes first
3. Run `pnpm generate` once after all changes
4. Run `pnpm migrate` once to apply
**Use Server-Side tRPC Caller:**
Import `caller` from `src/trpc/server.tsx` in server components or API routesRun router methods without HTTP6. High-Value Files to Read First
Must read before making changes:
`src/trpc/init.ts` — auth, context, and procedure helpers`src/trpc/server.tsx` — server caller, prefetch helpers, Hydration boundary`src/lib/db/schema.ts` — full DB schema, types and migration logic`src/auth.ts` & `src/auth.config.ts` — NextAuth configuration and callbacks7. What NOT to Change Without Review
Migration history in `drizzle/` (breaking changes will affect existing DBs)`src/lib/db/schema.ts`'s automatic migration runner (affects startup behavior)Authentication callbacks and adapter wiring in `src/auth.ts`Example Usage
**Protected tRPC mutation:**
```typescript
protectedProcedure
.input(z.object({ pennameid: z.string() }))
.mutation(async ({ input, ctx }) => {
// Reference: src/trpc/routers/works.ts
const userId = ctx.session.user.id;
// Your mutation logic here
})
```
**Server-side tRPC call:**
```typescript
import { caller } from '@/trpc/server';
// In a server component
const data = await caller.yourRouter.yourProcedure({ input });
```
Important Notes
Always batch schema changes before running `pnpm generate` and `pnpm migrate`Use existing shadcn/ui components instead of building from scratchKeep Tailwind classes simple; leave fine-tuning to the userNever manually create migration files; always use `pnpm generate`Migrations are applied automatically at startup by `src/lib/db/schema.ts`