Markdown Converter
Agent skill for markdown-converter
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Sign in to like and favorite skills
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Dentalize is a task management web application tailored for small dental practices. Built with Next.js 15, it features user authentication, a 7-day calendar interface, and management for Services, Clients, and Tasks. The entire UI is in Brazilian Portuguese (pt-BR).
# Install dependencies npm install # Run development server (http://localhost:3000) npm run dev # Build for production npm run build # Start production server npm start # Database operations export $(cat .env.local | xargs) && npx prisma studio # Open Prisma Studio export $(cat .env.local | xargs) && npx prisma migrate dev # Create migration export $(cat .env.local | xargs) && npx prisma generate # Generate Prisma client
Note: SQLite requires environment variables to be loaded. Prefix Prisma commands with
export $(cat .env.local | xargs) &&.
Three core entities with relationships:
Task statuses: SCHEDULED, IN_PROGRESS, COMPLETED, CANCELLED
app/ ├── (auth)/ # Grouped route for unauthenticated pages │ ├── login/ │ └── register/ ├── dashboard/ # Protected routes │ ├── layout.tsx # Sidebar navigation │ ├── page.tsx # Main 7-day calendar view │ ├── clientes/ # Client management │ └── servicos/ # Service management └── api/auth/ # NextAuth API routes components/ ├── ui/ # shadcn/ui base components ├── calendar/ # WeekView and TaskCard components ├── tasks/ # TaskForm modal ├── clients/ # (Future: client-specific components) └── services/ # (Future: service-specific components) actions/ # Server Actions for data mutations ├── auth.ts # register, login, logout ├── tasks.ts # CRUD for tasks ├── clients.ts # CRUD for clients └── services.ts # CRUD for services lib/ ├── auth.ts # NextAuth configuration ├── prisma.ts # Prisma client singleton └── utils.ts # Utility functions (cn for className merging) middleware.ts # Route protection and authentication checks
Server Actions: All data mutations use Next.js Server Actions instead of API routes. This provides type-safe mutations with automatic revalidation.
Protected Routes: Middleware checks authentication for
/dashboard/*, /clientes/*, /servicos/*, and /tarefas/* routes. Redirects to /login if unauthenticated.
Route Groups:
(auth) and dashboard group routes with shared layouts without affecting URL structure.
Prisma Singleton:
lib/prisma.ts ensures a single Prisma client instance in development to avoid connection exhaustion.
Optimistic UI: Dashboard pages fetch data client-side for interactivity, then revalidate after mutations using
revalidatePath().
startOfWeek(date, { weekStartsOn: 0 })startTime, with height calculated from duration (endTime - startTime)startOfWeek (Sunday)[Sunday, Monday, ..., Saturday]startTime >= weekStart && startTime <= weekEndregisterUser action hashes password with bcrypt → Creates user in DB → Redirects to login/dashboardlogoutUser action → Session cleared → Redirects to /loginreq.auth on protected routesactions/ directory"use server" directive at top of fileawait auth()revalidatePath() after mutationsExample:
"use server" import { auth } from "@/lib/auth" import { prisma } from "@/lib/prisma" import { revalidatePath } from "next/cache" export async function myAction(formData: FormData) { const session = await auth() if (!session?.user?.id) { return { error: "Não autenticado" } } // Perform database operation await prisma.model.create({ data: { ... } }) revalidatePath("/your-page") return { success: true } }
Update
.env.local:
DATABASE_URL="postgresql://user:password@localhost:5432/dentalize"
Update
prisma/schema.prisma:
datasource db { provider = "postgresql" url = env("DATABASE_URL") }
Run migration:
export $(cat .env.local | xargs) && npx prisma migrate dev
cn() utility for className mergingcomponents/ui/ for reusable components{ locale: ptBR }null (not cascade delete)@default(cuid()) for IDs (collision-resistant)startTime and endTime are DateTime (stored as ISO strings)duration is in minutes (Integer)price is Float (SQLite doesn't have Decimal type, use Float)[userId, startTime] and [startTime, endTime] for query performanceexport $(cat .env.local | xargs)NEXTAUTH_SECRET is set in .env.local