Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
18 changes: 18 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Claude Code Action
on:
issue_comment:
types: [created]
pull_request:
types: [opened, synchronize]

jobs:
claude-response:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
106 changes: 106 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Mexico Paradise Vacations — a travel certificate sales platform with payment plans, client portal, and admin dashboard. Built with Next.js 15 (App Router) + TypeScript + Tailwind CSS 4 + shadcn/ui.

## Commands

- **Dev server**: `npm run dev` (uses nodemon + tsx to run custom `server.ts`; HMR is disabled in favor of nodemon-based full reload)
- **Build**: `npm run build`
- **Production**: `npm run start`
- **Lint**: `npm run lint`
- **DB push schema**: `npm run db:push`
- **DB generate client**: `npm run db:generate`
- **DB migrate**: `npm run db:migrate`

## Architecture

### Custom Server (`server.ts`)
The app uses a custom Node HTTP server (not the default `next dev`/`next start`). It creates a Next.js app and attaches a Socket.IO server on `/api/socketio`. Dev mode runs via `nodemon --exec "npx tsx server.ts"`.

### Dual Database Setup
- **Supabase** (`src/lib/supabase.ts`): Primary data store for the business domain — users, signups, payments, certificates. The Supabase client is initialized with hardcoded project URL/anon key. Database types are defined inline in this file.
- **Prisma + SQLite** (`src/lib/db.ts`, `prisma/schema.prisma`): Secondary database with a basic User/Post schema. Uses the singleton pattern to avoid multiple PrismaClient instances in dev.

### Authentication
Simple demo auth in `src/lib/auth.ts` — password is hardcoded as `demo123`, user session stored in localStorage. Role-based: `admin` or `client`.

### Payment Integration
`src/lib/maverick.ts` — `MaverickPaymentAPI` class wrapping the Maverick Payments REST API. Configured via `MAVERICK_API_URL` and `MAVERICK_API_KEY` env vars.

### API Routes
All under `src/app/api/`:
- `POST /api/signup` — new vacation package signup
- `POST /api/payment/create` — create payment
- `POST /api/payment/confirm` — confirm payment status
- `POST /api/admin/refund` — process refund (admin only)
- `GET /api/health` — health check

### Pages
- `/` — landing page
- `/client-portal` — client dashboard (auth-guarded)
- `/admin-portal` — admin dashboard (auth-guarded)
- `/payment/success`, `/payment/cancel` — payment result pages

### UI Components
shadcn/ui (new-york style) in `src/components/ui/`. Custom components: `auth-guard.tsx`, `login-modal.tsx`.

## Path Aliases

`@/*` maps to `./src/*` (configured in tsconfig.json).

## Environment Variables

- `DATABASE_URL` — Prisma/SQLite connection string
- `NEXT_PUBLIC_APP_URL` — application URL
- `MAVERICK_API_URL` — Maverick Payments API base URL
- `MAVERICK_API_KEY` — Maverick Payments API key

## Build Notes

- TypeScript build errors are ignored (`typescript.ignoreBuildErrors: true` in next.config.ts)
- ESLint errors are ignored during builds (`eslint.ignoreDuringBuilds: true`)
- ESLint config is very permissive — most strict rules are turned off

## Best Practices

### Next.js App Router
- Use Server Components by default; only add `"use client"` when you need browser APIs, event handlers, or React hooks (useState, useEffect, etc.)
- Place data fetching in Server Components or API routes — never fetch in `useEffect` when a server-side approach works
- Use `route.ts` files for API routes; export named functions matching HTTP methods (`GET`, `POST`, `PUT`, `DELETE`)
- Return `NextResponse.json()` from API routes with appropriate status codes
- Use `loading.tsx`, `error.tsx`, and `not-found.tsx` for route-level UI states
- Use `layout.tsx` for shared UI that persists across navigations; avoid re-fetching data that a parent layout already provides
- Prefer Next.js `<Image>` over `<img>` and `<Link>` over `<a>` for optimized loading and client-side navigation
- Use `metadata` exports or `generateMetadata()` for SEO — not manual `<head>` tags

### Node.js / Server-Side
- Never block the event loop — use async/await for I/O, avoid synchronous file or network calls in request handlers
- Keep secrets in environment variables, never hardcode them (note: this project currently has hardcoded Supabase keys that should be moved to env vars)
- Use the Prisma singleton pattern from `src/lib/db.ts` to prevent connection exhaustion in dev
- Validate and sanitize all user input at API boundaries using Zod (already a dependency)
- Handle errors explicitly in API routes — return structured error responses, don't let unhandled exceptions leak stack traces
- Use `try/catch` around external API calls (Maverick, Supabase) and return meaningful error messages

### React / Frontend
- Co-locate component state as close to where it's used as possible; lift state only when siblings need to share it
- Use Zustand (already installed) for global client state; avoid prop drilling more than 2 levels deep
- Use React Query (`@tanstack/react-query`, already installed) for server state — caching, refetching, and optimistic updates
- Prefer controlled form inputs with `react-hook-form` + Zod validation (both already installed)
- Use shadcn/ui components from `src/components/ui/` — don't rebuild existing primitives
- Add new shadcn components via `npx shadcn@latest add <component-name>`

### TypeScript
- Use explicit return types on exported functions and API route handlers
- Define shared types/interfaces in dedicated files or alongside their domain (e.g., Supabase types in `src/lib/supabase.ts`)
- Prefer `interface` for object shapes that may be extended; use `type` for unions, intersections, and computed types
- Use Zod schemas as the single source of truth for validation and infer TypeScript types from them with `z.infer<>`

### Styling
- Use Tailwind CSS utility classes; avoid custom CSS unless Tailwind cannot express the style
- Follow the shadcn/ui `new-york` style variant (configured in `components.json`)
- Use CSS variables defined in `src/app/globals.css` for theme colors
- Use `cn()` from `src/lib/utils.ts` to merge conditional Tailwind classes (combines `clsx` + `tailwind-merge`)
12 changes: 12 additions & 0 deletions ecosystem.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
apps: [{
name: 'hi2b',
script: 'npx',
args: 'tsx server.ts',
cwd: '/opt/hi2b',
env: {
PORT: 3015,
NODE_ENV: 'production'
}
}]
}
6 changes: 5 additions & 1 deletion next.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
/* config options here */
images: {
remotePatterns: [
{ protocol: 'https', hostname: 'images.unsplash.com' },
],
},
typescript: {
ignoreBuildErrors: true,
},
Expand Down
Loading
Loading