Domain-driven design patterns for WITP project - strict layer isolation and dependency rules for modules, app, ai, infrastructure, and shared layers
This project strictly follows a Screaming Architecture (Domain-Driven Design applied to frontend/fullstack). The folder structure must immediately communicate the business purpose of the application ("What is This Pain?") rather than the framework being used.
You must strictly place new files into one of these 5 layers. Do not create new root folders.
app/: Next.js routing, pages, layouts, and external webhooks ONLY.modules/: Business domains. This is where the core logic lives.ai/: AI models, agent logic, and MCP server protocols.infrastructure/: Third-party adapters, database clients (Prisma), external API configs.shared/: Generic, domain-agnostic code (UI components, utils, global types).app/Code inside modules/, ai/, infrastructure/, or shared/ MUST NEVER import anything from app/. The app/ folder is the outermost presentation layer.
import { usePathname } from 'next/navigation' inside a modules/ logic file.app/ down to the module.Modules inside modules/ must remain independent. modules/anatomy-3d/ MUST NEVER directly import logic, components, or actions from modules/community/.
shared/store/ (Zustand) or compose them together at the app/ layer.NEVER instantiate Prisma directly inside a module or action.
infrastructure/db/prisma.import prisma from '@/infrastructure/db/prisma'Server Actions must live within their respective domain.
actions/ folder.modules/pain-tracking/actions.ts.When asked to create a new feature:
community, anatomy-3d, auth, etc.?).modules/[domain]/components/.modules/[domain]/actions.ts.modules/[domain]/schemas.ts.app/[lang]/....