its-done CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
IMPORTANT: Documentation Rules
NEVER CREATE NEW .md FILES IF ONE ALREADY EXISTS FOR THAT TOPIC!
The project maintains a minimal set of documentation files. When updating code:
- Docker changes → Update
DOCKER.md(don't create DOCKER-*.md) - Railway changes → Update
RAILWAY.md(don't create RAILWAY-*.md) - Architecture changes → Update
CLAUDE.md(this file)
Rule: One topic = One file. Always update existing files instead of creating new ones.
Project Overview
It's Done is a professional time tracking and invoicing system for freelancers and consultants. Built as a monorepo using Turborepo with a NestJS backend and Next.js frontend.
Key Commands
Development
# Start full development environment (RECOMMENDED)
pnpm dev # Smart script: stops existing services + starts + colored logs
# Individual services
cd apps/backend && pnpm dev # Backend only (port 3002)
cd apps/frontend && pnpm dev # Frontend only (port 3000)
# Alternative from any directory
pnpm start:dev # From frontend or backend folder
Build & Test
# Build
pnpm build # Build all apps
pnpm build:backend # Backend only
pnpm build:frontend # Frontend only
# Test
pnpm test # Run all tests
cd apps/frontend && pnpm test # Frontend tests with Jest
cd apps/backend && pnpm test # Backend tests with Jest
# Frontend test modes
cd apps/frontend
pnpm test:ci # CI mode (no watch)
pnpm test:coverage # With coverage report
Database (Prisma)
cd apps/backend
# Development
pnpm prisma generate # Generate Prisma client
pnpm prisma db push # Push schema changes
pnpm prisma migrate dev # Create and apply migration
pnpm prisma studio # Open Prisma Studio (port 5555)
# Seed data
pnpm db:seed # Seed development data
pnpm db:seed:prod # Seed production data
Code Quality
pnpm lint # Lint all packages
pnpm format # Format code with Prettier
Docker (Development & Production)
# Development (hot reload)
docker compose -f docker-compose.dev.yml up -d
docker compose -f docker-compose.dev.yml logs -f
# Production (test locally before Railway deploy)
docker compose up -d --build
docker compose logs -f
# See DOCKER.md for complete guide
Architecture
Monorepo Structure
- apps/backend: NestJS API (TypeScript, Prisma, PostgreSQL)
- apps/frontend: Next.js 14 App Router (React 18, TypeScript, TailwindCSS)
- packages/: Shared TypeScript configurations
Backend Modules (NestJS)
Located in apps/backend/src/:
auth/- JWT + Google OAuth authentication (guards, strategies)users/- User management with role-based access (USER/ADMIN)clients/- Client management with multiple addressesprojects/- Projects with hourlyRate for automatic invoice calculationwork-hours/- Time tracking entries linked to clients/projectsinvoices/- Invoice generation with file upload (Railway Volume → S3 → local fallback)addresses/- Multiple addresses per client (billing, shipping, office)settings/- User preferences and alert configurationnotifications/- Email notifications via Resend (hours alerts, invoice notifications)dashboard/- Metrics and analyticsreports/- Reporting functionalityadmin/- Admin panel (first user by ID is auto-admin)
Frontend Structure (Next.js App Router)
Located in apps/frontend/src/:
app/[locale]/- Internationalized routes (pt-BR, en)(authenticated)/- Protected routes requiring logindashboard/- Internal dashboard with tabs (Recent Work, Invoices, Clients)clients/- Client management with search and share functionalityprojects/- Project managementwork-hours/- Time entry interfaceinvoices/- Invoice management with search/filtersanalytics/- Advanced analyticssettings/- User settingsadmin/- Admin panel for user management
client-dashboard/[clientId]/- Public dashboard for clients to view their invoices
components/- Reusable componentsui/- Base UI components (Radix UI + Shadcn)- Feature-specific components (clients, invoices, work-hours, etc.)
services/- API client serviceshooks/- Custom React hookslib/- Utility functions
Database Schema (Prisma)
Key models in apps/backend/prisma/schema.prisma:
- User - Authentication, role (USER/ADMIN)
- Client - Contact info, belongs to User
- Address - Multiple addresses per Client (type: billing/shipping/office, isPrimary)
- Project - Linked to Client, has
hourlyRatefor invoice calculation - WorkHour - Time entries linked to User, Client, optional Project
- Invoice - Generated from WorkHours, has status (PENDING/PAID/CANCELED), file upload
- InvoiceWorkHour - Junction table linking Invoices to WorkHours (many-to-many)
- Settings - User preferences (alertHours, notificationEmail)
- NotificationLog - Audit trail for sent emails
Important Data Relationships
- User → Clients, Projects, WorkHours (1:N)
- Client → Projects, WorkHours, Invoices, Addresses (1:N)
- Project → WorkHours (1:N) - Each project has
hourlyRateused for invoice calculation - Invoice ↔ WorkHours (N:N via InvoiceWorkHour junction table)
- WorkHour can belong to only ONE Invoice (enforced by business logic)
Critical Business Logic
Invoice Calculation
IMPORTANT: Invoice amounts are calculated from project.hourlyRate:
- Each WorkHour associated with a Project uses that project's hourlyRate
- Total = Σ(workHour.hours × workHour.project.hourlyRate)
- If no project, hourlyRate defaults to 0
- This is a recent change - historically the rate was per-invoice
File Upload Strategy (Priority Order)
- Railway Volume (production) -
/app/dataifRAILWAY_ENVIRONMENTset - AWS S3 (fallback) - If AWS credentials configured
- Local Storage (development) -
uploads/directory
Authentication Flow
- NextAuth.js handles session management
- Supports Email/Password + Google OAuth2
- JWT tokens for backend API authentication
- Password reset via email with 1-hour expiry tokens
- Admin role: First user (by DB ID) is auto-admin
Notification System
- Hours Alert: Auto-email when user exceeds configured threshold (Settings.alertHours)
- Invoice Upload: Auto-email to client when invoice created
- Welcome Email: Sent on user registration
- Anti-spam: Uses NotificationLog to prevent duplicate alerts for same threshold
Client Dashboard (Public)
- Public route:
/client-dashboard/[clientId](no auth required) - Clients can view their invoices, hours worked, and download files
- Share via WhatsApp, Email, or copy link from Clients page
Key Features & Components
Dashboard System
- Unified Component: Single dashboard component supports both internal and client modes
- Internal Dashboard (
/dashboard): Admin view with tabs for Recent Work, Invoices, Clients - Client Dashboard (
/client-dashboard/[clientId]): Public portal for clients
Search & Filtering
- InvoiceSearchFilters component: Reusable search/filter component
- Search by invoice number, description, or client name
- Filter by status (All, Paid, Pending, Canceled)
- Sort by date, amount, status, or hours
- Live result counter
Design System
- BigStatsDisplay: Colored stats cards per page (blue for clients, indigo for projects, purple for invoices, green for work hours)
- Card Components: Themed cards (ClientCard, ProjectCard, InvoiceCard, WorkHourCard) with consistent styling
- PageHeader: Standardized header with icon, title, description, and action buttons
- InfoCard: Context-aware info boxes with themed colors
Internationalization
- Uses
next-intlfor i18n (pt-BR, en) - Translation files:
apps/frontend/src/messages/{locale}.json - Form-specific translations: Separate keys for form subtitles vs page descriptions
- Example:
editClientFormSubtitlevseditClientDescription
- Example:
- Custom time formatting:
formatTimeAgo()function uses custom translations instead of date-fns locale
Avatar System
- Intelligent fallback chain: Google Profile → Gravatar → UI Avatars → DiceBear → Local SVG
- Handles DNS failures gracefully
- 5-minute cache for successful avatars
Testing
Frontend Tests (Jest + Testing Library)
- Located in
__tests__/directories next to components - Run with
pnpm testfromapps/frontend - Key test files:
- Component tests for major features
- Translation consistency tests
- Form modal integration tests
Backend Tests (Jest)
- Located next to source files (
.spec.ts) - Run with
pnpm testfromapps/backend - Includes unit and integration tests
Environment Variables
Backend (.env)
DATABASE_URL="postgresql://..."
JWT_SECRET="..."
RESEND_API_KEY="..." # Email service
FROM_EMAIL="..."
GOOGLE_CLIENT_ID="..." # OAuth (optional)
GOOGLE_CLIENT_SECRET="..."
RAILWAY_VOLUME_PATH="/app/data" # Production storage
AWS_ACCESS_KEY_ID="..." # S3 fallback (optional)
AWS_SECRET_ACCESS_KEY="..."
AWS_S3_BUCKET="..."
Frontend (.env.local)
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="..."
API_URL="http://localhost:3002"
GOOGLE_CLIENT_ID="..." # Must match backend
GOOGLE_CLIENT_SECRET="..."
Deployment
Railway (Recommended)
- Auto-deploy on push to
mainbranch - Uses Dockerfiles in
apps/backend/andapps/frontend/ - Railway Volume for persistent file storage (1GB)
- See
RAILWAY_COMPLETE_GUIDE.mdfor detailed setup
Docker
- Multi-stage builds optimized for production
- Backend:
apps/backend/Dockerfile - Frontend:
apps/frontend/Dockerfile(uses Next.js standalone output)
Important Patterns & Conventions
Code Organization
- By feature, not type: Backend modules group controllers/services/DTOs together
- Absolute imports: Use path aliases (
@/components, not../../components) - DTO validation: Use
class-validatordecorators on all DTOs - Type safety: Prisma types extended in
apps/backend/src/types/entities.ts
API Standards
- RESTful endpoints with
/apiprefix - JWT authentication via
@UseGuards(JwtAuthGuard) - Admin routes protected with
@UseGuards(AdminGuard) - Public routes:
/api/public/*(e.g., client dashboard data)
Frontend Patterns
- Server Components by default (Next.js 14 App Router)
- Client Components: Use
'use client'directive sparingly - Data fetching: TanStack Query (React Query) for client-side data
- Forms: React Hook Form + Zod validation
- Styling: TailwindCSS with
cn()utility for conditional classes
Error Handling
- Backend: Custom
GlobalExceptionFilterinapps/backend/src/global.filter.ts - Frontend: Try-catch with toast notifications (Sonner)
- Sentry integration for error tracking
Common Tasks
Adding a New Feature Module (Backend)
- Generate module:
nest g module feature-name - Add service:
nest g service feature-name - Add controller:
nest g controller feature-name - Create DTOs in
dto/folder with validation decorators - Update Prisma schema if needed, then
pnpm prisma migrate dev - Import module in
app.module.ts
Adding a New Page (Frontend)
- Create route in
app/[locale]/(authenticated)/your-page/page.tsx - Use PageHeader and PageContainer for layout consistency
- Add translations to
messages/en.jsonandmessages/pt-BR.json - Create feature components in
components/your-feature/ - Add navigation link in layout sidebar if needed
Running a Single Test
# Frontend
cd apps/frontend
pnpm test -- path/to/test.test.tsx
# Backend
cd apps/backend
pnpm test -- path/to/test.spec.ts
Third-Party Integrations
- Resend: Email service (notifications, password reset)
- Google OAuth: Social authentication
- Railway: Hosting platform with volume storage
- AWS S3: Fallback file storage
- Sentry: Error tracking and monitoring
- Prisma: ORM and database toolkit
Performance Considerations
- Frontend uses Next.js Server Components for reduced client-side JS
- TanStack Query provides intelligent caching and background refetching
- Images should use Next.js
<Image>component for optimization - Database queries use Prisma's relation loading to avoid N+1 problems
- File uploads: 10MB limit enforced at backend
Security Notes
- First user (by database ID order) is automatically admin
- Admin guard checks
user.role === 'ADMIN' - File uploads validated by MIME type and extension
- JWT tokens stored in HTTP-only cookies
- CORS configured for frontend origin only
- Rate limiting should be implemented (currently not enforced)