Fullstack: One Team, Every Layer
Fullstack teams build features from database to UI: data model, API endpoint, business logic, and frontend component — all in one PR. The advantage: one team owns the full feature. The risk: without clear boundaries, fullstack code becomes tangled — frontend logic leaks into the backend, backend types are duplicated in the frontend, and a change in one layer breaks another. AI rules for fullstack teams enforce: clear layer separation, shared types across the stack, and consistent patterns at each layer.
The modern fullstack stack: Next.js (App Router with Server Components, Server Actions, and API routes), Remix (loaders and actions), SvelteKit (server load functions), or Nuxt (server routes and composables). These frameworks blur the line between frontend and backend — Server Components run on the server but look like React components. AI rule: 'Understand the framework's server/client boundary. Next.js: Server Components (server-only), Client Components (browser), Server Actions (server functions called from the client). Generate code on the correct side of the boundary.'
The fullstack AI rules: types are defined once and shared, API contracts are explicit (tRPC, Zod schemas, or OpenAPI), business logic lives in a separate layer (not in components or API handlers), and database queries never run in client code.
Layer Boundaries and Data Flow
Server vs client boundary: AI rule: 'In Next.js App Router: Server Components are the default (server-rendered, no client JavaScript). Add "use client" only when the component needs: browser APIs, event handlers (onClick, onChange), state (useState), or effects (useEffect). The AI should generate Server Components by default and only add "use client" when required. This minimizes client-side JavaScript.'
Business logic layer: AI rule: 'Business logic (validation, calculations, transformations, authorization) lives in a separate layer — not in API handlers and not in UI components. Pattern: handlers call service functions, services contain business logic, services call repositories for data access. The AI generates: thin handlers (parse input, call service, format response), service functions (business logic), and data access functions (database queries). This separation makes business logic testable without HTTP or UI.'
Data flow: AI rule: 'Data flows in one direction: database → server → client. The client never directly queries the database. Server Actions and API routes are the boundary. The client sends user input to the server, the server validates and processes it, and the server returns the result. The AI must never generate database imports or queries in client components or files without "use server" directives.'
In Next.js: importing a database client in a file without 'use server' can accidentally expose the database connection to the client bundle. The AI must ensure: database imports only exist in server-only files (Server Components, Server Actions, API routes). Client Components (files with 'use client') must never import database modules. Use the server-only package to enforce this: import 'server-only' at the top of files that should never be bundled for the client.
Fullstack Feature Development Patterns
Feature structure: AI rule: 'Fullstack features organized by domain: features/users/ contains: schema.ts (Zod schema, shared), service.ts (business logic, server), api.ts or route.ts (API handler, server), and components/ (UI components, client). All related code in one directory. The AI generates the full feature structure when creating a new feature, not just one layer.'
Form handling: the most common fullstack pattern. AI rule: 'Form data flow: client (form component with validation) → server (Server Action or API endpoint with same Zod validation) → database (validated data inserted/updated). Client-side validation: for instant UX feedback. Server-side validation: for security (client validation can be bypassed). Same Zod schema for both. The AI generates both client and server validation from the shared schema.'
Optimistic updates: update the UI immediately, then sync with the server. If the server rejects the update: revert the UI. AI rule: 'For actions where latency matters (like, bookmark, toggle): use optimistic updates. Pattern: update the UI state immediately, send the request to the server, if the server returns an error: revert the UI state and show an error message. TanStack Query: useMutation with onMutate (optimistic update) and onError (rollback). The AI generates optimistic patterns for user-facing actions where instant feedback matters.'
With layer-based folders (api/users.ts, components/UserProfile.tsx, schemas/user.ts): a fullstack feature change touches 3+ directories. PR reviews hop between unrelated files. With feature folders (features/users/ containing schema.ts, service.ts, api.ts, UserProfile.tsx): the entire feature is in one directory. The PR changes are co-located. Reviewers see the full picture. Deleting a feature: remove one folder.
Fullstack AI Rules Summary
Summary of AI rules for fullstack teams building end-to-end features.
- Shared types: define once (Zod schema or Drizzle inferred type). Used by server and client
- tRPC: end-to-end type safety. Procedures with Zod input. Never bypass with raw fetch
- Server Components: default in Next.js. Add 'use client' only when browser APIs needed
- Business logic: separate service layer. Not in handlers, not in components. Testable independently
- Data flow: database → server → client. Client never queries database directly
- Feature structure: organized by domain. Schema + service + API + components in one directory
- Forms: same Zod schema for client and server validation. Both are required
- Optimistic updates: instant UI feedback for user actions. Revert on server error