# Nuxt 3 + Vue + PostgreSQL — AI Agent Guidelines & Architecture Rules

> Production guidelines for Nuxt 3 server routes and universal rendering, Vue 3 Composition API, and PostgreSQL via a typed query layer.
> Technologies: Nuxt, Vue, PostgreSQL, Supabase, TypeScript, Tailwind CSS

---

## AGENTS.md
```markdown
# Project Architecture & Guidelines (Nuxt 3 + Vue + PostgreSQL)

## 1. System Architecture
- **Framework**: Nuxt 3 (Vue 3 Composition API, `<script setup>`, universal rendering).
- **Server Layer**: Nitro server routes in `server/api/` for backend logic — Nuxt ships its own request-handling runtime, no separate Express/Fastify process needed.
- **Database**: PostgreSQL, accessed from server routes only, via a typed query layer (Drizzle ORM or `postgres`/`pg` with hand-written types) — for solo builders and small teams, default to a managed provider (Supabase or Neon) rather than operating your own instance. The self-hosted examples below (Baserow, Directus, n8n) run their own Postgres because they're full self-hostable platforms, not because a typical Nuxt app needs to.
- **Validation**: TypeScript strict mode + Zod (or `valibot`) for both server route input and form validation.

## 2. Server Routes & Data Access
- Define API endpoints as files under `server/api/` (e.g. `server/api/projects.get.ts`, `server/api/projects/[id].patch.ts`) — the filename encodes the route and HTTP method.
- Never import a database client into a `.vue` component or a `composables/` file that runs on the client; database access is server-route-only.
- Use `useFetch`/`useAsyncData` in components/pages to call server routes with automatic SSR data hydration — avoid raw `fetch` in `onMounted` for data needed on first render.

## 3. Composition API Conventions
- Extract shared reactive logic into `composables/` (auto-imported by Nuxt); one concern per composable (`useAuth`, `useProjectFilters`).
- Prefer `<script setup lang="ts">` with typed `defineProps`/`defineEmits` over the Options API for all new components.
- Use Pinia for cross-page client state; avoid global mutable state outside a store.

## 4. Database Client & Migrations
- Singleton PostgreSQL client instantiated once in a Nitro plugin or a `server/utils/db.ts` module, reused across requests.
- If using Drizzle: `drizzle-kit generate` for migrations, applied via a deploy-time migration script — never `drizzle-kit push` in production.
- Default to Supabase or Neon for the database itself (managed Postgres, free tier, zero server ops) — use their built-in pooler (Supabase's transaction pooler, or Neon's pooled connection string) when deploying server routes to a serverless/edge runtime, since each cold start can otherwise open a new connection.

## 5. Common Pitfalls / Coding Standards
- ❌ Calling `fetch('/api/...')` directly instead of `useFetch`/`$fetch` — loses SSR hydration and can cause duplicate requests on the client.
- ❌ Putting database credentials in `runtimeConfig.public` instead of the private `runtimeConfig` — public config ships to the browser.
- ✅ Validate every server route's `body`/`query` with Zod before it reaches the database layer.

## 6. Testing Conventions
- Vitest with `@nuxt/test-utils` for unit/component tests, and for testing server routes in isolation.
- Playwright for e2e coverage of critical flows (auth, checkout, primary CRUD screens).
- Run `nuxi typecheck` (wraps `vue-tsc`) as a required check — plain `tsc` doesn't understand `.vue` SFCs.

## 7. Git Workflow & PR Conventions
- Conventional Commits scoped to the route or composable, e.g. `fix(api/projects): enforce owner check on delete`.
- Generated migrations ship in the same PR as the schema change they correspond to.
- Require `nuxi typecheck` and `bun run build` green before merge.
- Squash-merge; never run a migration `push` directly against a shared or production database from a feature branch.
```

---

## CLAUDE.md
```markdown
# CLAUDE.md — Nuxt 3 + Vue + PostgreSQL

Refer to @AGENTS.md for complete database configuration and architectural constraints.

## Common Commands
- `bun run dev` - Start local Nuxt development server
- `bun run build` - Build production Nuxt bundle (Nitro)
- `bun run nuxi typecheck` - Type-check `.vue` SFCs and server routes
- `bun run db:generate` - Generate migration files (if using Drizzle)

## Claude Specific Directives
- Database access only from `server/api/` routes or `server/utils/`; never from a `.vue` file or client composable.
- Use `useFetch`/`$fetch` for calling server routes, not raw `fetch`.
```

---

## .cursor/rules/stack.mdc
```markdown
---
description: Nuxt 3 + Vue + PostgreSQL architecture rules
globs: ["**/*.vue", "**/*.ts"]
alwaysApply: true
---

# Nuxt 3 + Vue + PostgreSQL

- Nuxt 3 with Vue 3 Composition API and `<script setup lang="ts">`; Nitro server routes in `server/api/` handle all backend logic.
- Database access is server-route-only — never import a DB client into a `.vue` component or client-side composable.
- Use `useFetch`/`useAsyncData`/`$fetch` for calling server routes, never raw `fetch` in `onMounted`.
- Shared reactive logic goes in auto-imported `composables/`; Pinia for cross-page client state.
- Validate every server route's input with Zod/valibot before it touches PostgreSQL.
- Keep database credentials in the private `runtimeConfig`, never `runtimeConfig.public`.
- Run `nuxi typecheck` (wraps `vue-tsc`) before considering a change complete.
```

---

## Architecture Overview & Best Practices
## Architecture Overview

Standardized production guidelines for **Nuxt 3**, **Vue 3 Composition API**, and **PostgreSQL**, using Nitro server routes as the backend layer.

### Verified Real-World Adoption

This pattern is the backbone of several production internal-tool and developer-tool platforms: **Baserow** (no-code database, Nuxt + Vue frontend over a Django/FastAPI + PostgreSQL backend), **Hoppscotch** (API testing client, Vue + Nuxt + Node + PostgreSQL), **Directus** (headless CMS, Vue + Node + PostgreSQL), **n8n** (workflow automation, Vue + Node + PostgreSQL), and **NocoDB** (smart spreadsheet, Vue + Node + PostgreSQL/MySQL).

### Key Architectural Nuances

- **Nitro as the Backend**: Server routes deploy as part of the same Nuxt build output, targeting Node, Deno, or edge runtimes without a separate backend service to provision.
- **SSR Payload Reuse**: `useFetch`/`useAsyncData` deduplicate server-rendered data on hydration, avoiding the double-fetch flash common in naive SPA-over-API setups.