Imported from konoec/reserva-saas (
AGENTS.md). Install upstream withnpx skills add konoec/reserva-saas. Copyright stays with the author.
This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ before writing any code. Heed deprecation notices.
Reserva SaaS — Restaurant Reservations + Table Management
Stack
- Next.js 16 (App Router, RSC) + TypeScript, React 19
- Postgres on Supabase, Prisma 7 (
prisma-clientgenerator, driver adapter@prisma/adapter-pg) - Tailwind CSS v4 + shadcn/ui
- Auth.js (Auth.js, planned Fase 2), Stripe (planned), Resend (planned)
Commands
npm run dev— start dev servernpm run lint— ESLintnpm run typecheck— tsc --noEmitnpm run db:migrate—prisma migrate devnpm run db:deploy—prisma migrate deploy(prod)npm run db:studio— Prisma Studionpm run db:generate— regenerate Prisma Client
Always run lint + typecheck after code changes.
Prisma 7 specifics (breaking vs training data)
- No
urlindatasource dbblock. URL lives inprisma.config.ts(DIRECT_URLfor CLI migrations). - Runtime client uses driver adapter:
new PrismaClient({ adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL }) }). Seesrc/lib/db.ts. - Client generated to
src/generated/prisma(gitignored). Import from@/generated/prisma/client. - Never edit generated files; run
npm run db:generateafter schema changes.
Database / multi-tenancy
- Times stored in UTC (DateTime). Convert to
Organization.timezonein business layer. Never store local time. - Every tenant model is scoped by
organizationId. Always include org filter in queries. No RLS — app-level scoping. Organization.configis JSON: openingHours, avgDwellMinutes, bufferMinutes, maxPartySize, acceptWalkIns, closedDates. Validate with zod, never trust raw JSON.- Enums: Role, TableStatus, ReservationStatus, ReservationSource, SubscriptionStatus (see prisma/schema.prisma).
Structure
src/app/(auth)/— login/signup routessrc/app/(dashboard)/— authenticated app layoutsrc/app/(marketing)/— landing page (currentlysrc/app/page.tsx)src/components/ui/— shadcn components (do not hand-edit)src/components/— app componentssrc/lib/— db, auth, utils, org helperssrc/server/actions/— Server Actions (mutations)src/generated/prisma/— generated Prisma client (gitignored)
Conventions
- Server Actions for mutations, always verify auth + org ownership inside every action.
refresh()fromnext/cache(notrouter.refresh()) to refresh after mutations.cookies()fromnext/headersis async — await it.- shadcn components: use
npx shadcn@latest add <name>. - No comments in code unless explaining non-obvious logic.