Skip to main content

Project Structure

hans.ai is built as a monorepo using Turborepo, with the following structure:
notify-me/
├── apps/
│   ├── web/          # Next.js web application
│   └── docs/         # Mintlify documentation
├── packages/         # Shared packages (future)
├── turbo.json        # Turborepo configuration
└── package.json      # Root workspace configuration

Technology Stack

Frontend

  • Next.js 15 - React framework with App Router
  • TypeScript - Type-safe development
  • Tailwind CSS - Utility-first CSS framework
  • Zustand - State management
  • Radix UI - Accessible component primitives

Backend

  • Next.js API Routes - API endpoints
  • Prisma - Database ORM
  • PostgreSQL - Primary database
  • Better Auth - Authentication system
  • Resend - Email service
  • OpenAI - AI-powered features

Infrastructure

  • Turborepo - Monorepo management
  • Vercel - Deployment platform
  • Stagehand - Browser automation

Development Commands

Root Commands (Monorepo)

# Install dependencies
yarn install

# Run all apps in development
yarn dev

# Build all apps
yarn build

# Run linting
yarn lint

# Format code
yarn format

Web App Commands

Navigate to apps/web or use turbo from root:
# Database commands
yarn db:migrate    # Run migrations
yarn db:generate   # Generate Prisma client
yarn db:push      # Push schema changes
yarn db:studio    # Open Prisma Studio
yarn db:seed      # Seed database

# Development
yarn dev          # Start dev server with cron
yarn dev:server   # Start only Next.js server
yarn dev:cron     # Start only cron jobs

Environment Variables

Create a .env.local file in apps/web:
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/notify_me"

# Authentication
BETTER_AUTH_SECRET="generate-a-secure-random-string"
BETTER_AUTH_URL="http://localhost:3010"

# Email Service
RESEND_API_KEY="re_xxxxxxxxxxxxx"
EMAIL_FROM="[email protected]"

# OpenAI
OPENAI_API_KEY="sk-xxxxxxxxxxxxx"

# Polar (Payments)
POLAR_API_KEY="polar_xxxxxxxxxxxxx"
NEXT_PUBLIC_POLAR_CHECKOUT_LINK="https://buy.polar.sh/..."

# Stagehand (Browser Automation)
STAGEHAND_API_KEY="optional-api-key"

Database Schema

The application uses Prisma with PostgreSQL. Key models include:
  • User - User accounts and authentication
  • NotificationTask - Monitoring configurations
  • Action - Notification actions (email, webhook)
  • TaskExecution - Execution history
  • EvaluationResult - Evaluation outcomes

Testing

Running Tests

# Run all tests
yarn test

# Run tests in watch mode
yarn test:watch

# Run E2E tests
yarn test:e2e

Writing Tests

Place test files next to the code they test:
src/
├── components/
│   ├── Button.tsx
│   └── Button.test.tsx
└── lib/
    ├── utils.ts
    └── utils.test.ts

Code Style

The project uses:
  • ESLint for linting
  • Prettier for formatting
  • TypeScript strict mode

Git Hooks

Pre-commit hooks ensure code quality:
  • Format with Prettier
  • Lint with ESLint
  • Type check with TypeScript

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Ensure all tests pass
  6. Submit a pull request

Debugging

VS Code Configuration

.vscode/launch.json:
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "yarn",
      "runtimeArgs": ["dev:server"],
      "cwd": "${workspaceFolder}/apps/web",
      "env": {
        "NODE_OPTIONS": "--inspect"
      }
    }
  ]
}

Common Issues

Ensure PostgreSQL is running and DATABASE_URL is correct:
# Check PostgreSQL status
pg_isready

# Test connection
psql $DATABASE_URL
Regenerate the Prisma client: bash yarn db:generate
The dev server runs on port 3010. Kill the process:
lsof -i :3010
kill -9 <PID>