# CLAUDE.md

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

## Project Overview

**OGB Solutions** is a personal branding website built on PayloadCMS 3.64.0 and Next.js 15.4.7. The project serves as Oscar Gimenez's professional portfolio and meets Kit Digital grant requirements for Spanish businesses.

**Technology Stack:**
- PayloadCMS 3.64.0 (headless CMS)
- Next.js 15.4.7 (App Router)
- React 19.1.0
- PostgreSQL (via @payloadcms/db-postgres)
- TypeScript 5.7.3
- TailwindCSS 3.4.3 + shadcn/ui
- Lexical editor for rich text
- pnpm (package manager)

**Related Project:** This project is derived from `/home/oscar/daemez.io/x/daemez.solutions`, a B2B corporate site. When adding features, you may reference Daemez for structure but adapt content and tone for personal branding rather than corporate B2B.

## Essential Commands

### Development
```bash
# Install dependencies
pnpm install

# Start development server (http://localhost:3000)
pnpm dev

# Build for production
pnpm build

# Start production server
pnpm start

# Dev with production mode (clean build + start)
pnpm dev:prod
```

### Code Quality
```bash
# Run linter
pnpm lint

# Fix linting issues
pnpm lint:fix

# Run all tests (integration + e2e)
pnpm test

# Run integration tests only (Vitest)
pnpm test:int

# Run e2e tests only (Playwright)
pnpm test:e2e
```

### PayloadCMS Operations
```bash
# Generate TypeScript types from Payload config
pnpm generate:types

# Generate import map for admin panel
pnpm generate:importmap

# Access Payload CLI directly
pnpm payload [command]
```

### Database Operations (PostgreSQL)

**Local development:** The Postgres adapter has `push: true` enabled for development, allowing schema changes without migrations. This is safe ONLY when pointing to a local database.

**Creating migrations (when deploying to production):**
```bash
# Create a new migration after schema changes
pnpm payload migrate:create

# Run pending migrations on server
pnpm payload migrate
```

**Important:** Never run migrations with `push: true` against production data.

## Architecture

### Monorepo Structure

This is a **monorepo** with backend (PayloadCMS) and frontend (Next.js) in the same codebase:

```
src/
├── app/                    # Next.js App Router
│   ├── (frontend)/         # Public website routes
│   └── (payload)/          # PayloadCMS admin panel
├── collections/            # Payload collections (data models)
│   ├── Pages/              # Landing pages with layout builder
│   ├── Posts/              # Blog posts with rich content
│   ├── Media/              # Uploads (images, files)
│   ├── Categories/         # Taxonomy for organizing posts
│   └── Users/              # Authentication-enabled users
├── globals/                # Site-wide settings
│   ├── Header/             # Navigation configuration
│   └── Footer/             # Footer configuration
├── blocks/                 # Reusable content blocks for layout builder
│   ├── ArchiveBlock/       # Post listings
│   ├── CallToAction/       # CTA sections
│   ├── Content/            # Rich text content
│   ├── MediaBlock/         # Image/video blocks
│   ├── Banner/             # Alert/announcement banners
│   ├── Code/               # Syntax-highlighted code blocks
│   └── Form/               # Contact forms
├── heros/                  # Hero section variants
│   ├── HighImpact/         # Full-screen hero
│   ├── MediumImpact/       # Standard hero
│   ├── LowImpact/          # Minimal hero
│   └── PostHero/           # Blog post hero
├── components/             # React components
├── fields/                 # Reusable Payload field configs
├── access/                 # Access control policies
├── hooks/                  # Payload lifecycle hooks
├── utilities/              # Helper functions
└── payload.config.ts       # Main Payload configuration
```

### Key Architectural Patterns

#### 1. Layout Builder System
Pages use a **blocks-based layout builder** that allows content editors to compose pages from reusable blocks. Each block has:
- `config.ts` - Payload field configuration
- `Component.tsx` - React component for frontend rendering
- Server-side rendering via Next.js App Router

#### 2. Draft Preview & Live Preview
Both Pages and Posts support:
- **Draft mode**: Preview unpublished content via secure tokens
- **Live preview**: Real-time preview in admin panel while editing
- **Scheduled publishing**: Uses Payload jobs queue for timed publication

#### 3. On-Demand Revalidation
Hooks automatically revalidate Next.js cache when content changes:
- `revalidatePage` - Triggered on page updates
- `revalidatePost` - Triggered on post updates
- `revalidateHeader` - Triggered on navigation changes
- `revalidateFooter` - Triggered on footer changes

#### 4. SEO Integration
Using `@payloadcms/plugin-seo` for comprehensive SEO management:
- Auto-generates meta tags
- Open Graph support
- Twitter Card support
- Sitemap generation (via `next-sitemap`)

#### 5. Access Control
Three-tier access system:
- `authenticated` - Only logged-in users
- `authenticatedOrPublished` - Users or published content (public)
- `anyone` - Public access

Collections enforce access at the API level, not just UI.

### Collections Deep Dive

#### Pages Collection
- **Purpose**: Marketing pages, landing pages, about, contact
- **Features**: Layout builder with hero variants, draft preview, SEO
- **Blocks Available**: CallToAction, Content, MediaBlock, Archive, FormBlock
- **URL Pattern**: `/{slug}` (homepage is slug: "home")

#### Posts Collection
- **Purpose**: Blog articles, news, thought leadership
- **Features**: Rich text editor (Lexical), categories, related posts, author attribution
- **Content Blocks**: Banner, Code, MediaBlock (inline content blocks)
- **URL Pattern**: `/posts/{slug}`

#### Media Collection
- **Purpose**: Asset management (images, videos, files)
- **Features**: Focal point selection, manual resizing, responsive image optimization
- **Storage**: Uses Sharp for image processing

#### Categories Collection
- **Purpose**: Taxonomy for organizing posts
- **Features**: Nested categories (via `@payloadcms/plugin-nested-docs`)
- **Current Limitations**: Basic implementation (name + slug only)

#### Users Collection
- **Purpose**: Admin authentication
- **Features**: Access to admin panel, content authorship
- **Security**: Authentication required for all CMS operations

### Important Conventions

#### Path Aliases
TypeScript path aliases are configured in `tsconfig.json`:
- `@/*` → `src/*` (all source files)
- `@payload-config` → `src/payload.config.ts` (Payload config)

#### Admin Component References
Payload admin components use file-based imports with hash notation:
```typescript
components: {
  RowLabel: '@/Header/RowLabel#RowLabel'
}
```

#### Hook Execution
Payload hooks run in this order:
1. `beforeValidate`
2. `beforeChange`
3. `afterChange`
4. `afterRead`
5. `afterDelete`

Use `beforeChange` for data transformation, `afterChange` for side effects (like revalidation).

#### Environment Variables
Required variables (see `.env.example`):
- `DATABASE_URI` - PostgreSQL connection string
- `PAYLOAD_SECRET` - JWT encryption key
- `NEXT_PUBLIC_SERVER_URL` - Base URL for links/CORS
- `CRON_SECRET` - For scheduled publishing authentication
- `PREVIEW_SECRET` - For secure draft previews

## Plugin Configuration

### Active Plugins
1. **@payloadcms/plugin-form-builder** - Contact forms with email notifications
2. **@payloadcms/plugin-search** - Full-text search (currently posts only)
3. **@payloadcms/plugin-nested-docs** - Hierarchical categories
4. **@payloadcms/plugin-seo** - Meta tags, Open Graph, Twitter Cards
5. **@payloadcms/plugin-redirects** - URL redirect management

### Plugin Configuration Location
All plugins configured in `src/plugins/index.ts`. When adding new collections to search, update the `searchPlugin` collections array.

## Testing Strategy

### Integration Tests (Vitest)
- Location: `tests/int/**/*.int.spec.ts`
- Purpose: Test Payload API endpoints, hooks, access control
- Environment: jsdom with React testing library
- Run: `pnpm test:int`

### E2E Tests (Playwright)
- Location: `tests/e2e/**/*.e2e.spec.ts`
- Purpose: Test full user flows, admin panel, frontend
- Browser: Chromium (Desktop Chrome)
- Run: `pnpm test:e2e`

### Running Single Tests
```bash
# Single integration test
pnpm exec vitest run tests/int/api.int.spec.ts

# Single e2e test
pnpm exec playwright test tests/e2e/frontend.e2e.spec.ts
```

## Grant Requirements (Kit Digital)

This project must meet Spanish government grant requirements. Ensure these features remain functional:

### Mandatory Features
- ✅ Minimum 3 pages (home, about, contact)
- ✅ Responsive design (mobile, tablet, desktop)
- ✅ Contact form functionality
- ✅ WCAG 2.1 AA accessibility compliance
- ✅ Self-managed CMS (PayloadCMS admin)
- ✅ SEO optimization (meta tags, sitemap)
- ✅ 12-month hosting and domain in beneficiary name

### Testing Accessibility
```bash
# Run Playwright accessibility tests
pnpm test:e2e

# Manual check: Chrome DevTools Lighthouse
# 1. pnpm dev
# 2. Open http://localhost:3000
# 3. Chrome DevTools → Lighthouse → Run accessibility audit
```

## Development Workflow

### Adding a New Collection

1. Create collection file in `src/collections/CollectionName/index.ts`
2. Define fields, access control, hooks
3. Register in `src/payload.config.ts` collections array
4. Run `pnpm generate:types` to update TypeScript types
5. Add to search plugin if searchable (in `src/plugins/index.ts`)
6. Create migration if deploying to production: `pnpm payload migrate:create`

### Adding a New Block

1. Create block directory in `src/blocks/BlockName/`
2. Add `config.ts` (Payload field config)
3. Add `Component.tsx` (React rendering component)
4. Register block in relevant collection (Pages or Posts)
5. Add to `RenderBlocks.tsx` for frontend rendering

### Adding a New Page

1. Log into admin: `http://localhost:3000/admin`
2. Navigate to Pages collection
3. Click "Create New"
4. Set slug (e.g., "about" → URL: `/about`)
5. Choose hero type
6. Build layout with blocks
7. Configure SEO metadata
8. Save as draft or publish

### Modifying Header/Footer

1. Navigate to Globals → Header or Footer in admin
2. Modify navigation items
3. Changes automatically revalidate frontend via hooks
4. For code changes, edit `src/Header/config.ts` or `src/Footer/config.ts`

## Common Pitfalls

### TypeScript Errors After Schema Changes
**Problem:** TypeScript errors about missing fields after changing Payload config.
**Solution:** Always run `pnpm generate:types` after modifying collections/globals.

### Image Not Loading
**Problem:** Uploaded images return 404.
**Solution:**
- Check `NEXT_PUBLIC_SERVER_URL` in `.env`
- Verify Sharp installation: `pnpm rebuild sharp`
- Check `next.config.js` remotePatterns configuration

### Draft Preview Not Working
**Problem:** Preview links return 404 or show published version.
**Solution:**
- Verify `PREVIEW_SECRET` in `.env`
- Check `generatePreviewPath` utility is correctly configured
- Ensure draft is saved before previewing

### Revalidation Not Triggering
**Problem:** Content changes don't appear on frontend immediately.
**Solution:**
- Check hooks are registered in collection config
- Verify Next.js is running in dev mode (revalidation is automatic)
- In production, check `afterChange` hooks are executing

### Migration Conflicts
**Problem:** `pnpm payload migrate` fails with conflicts.
**Solution:**
- Never run migrations against a database with `push: true`
- Set `push: false` in `payload.config.ts` for production databases
- Manually resolve migration conflicts in generated SQL files

## Project-Specific Notes

### Personal Branding vs Corporate
This is a **personal branding** website, not corporate B2B. When adding features:
- Use first-person tone ("I", "my work") not third-person ("we", "our services")
- Focus on portfolio/projects, not services/products
- CTAs should be "Hire Me", "Get in Touch", not "Request Demo"

### Future Enhancements Planned
Based on `OGB_SETUP_GUIDE.md`, these collections may be added:
- **Projects** - Portfolio items, case studies
- **Skills** - Technology expertise tags
- **Experience** - Career timeline
- **Speaking** - Conference talks, publications

When implementing these, reference `/home/oscar/daemez.io/x/daemez.solutions/src/collections/` for structural inspiration.

### Localization
Currently English-only. Multilingual support may be added via:
```typescript
// In payload.config.ts
localization: {
  locales: [
    { label: 'English', code: 'en' },
    { label: 'Español', code: 'es' },
  ],
  defaultLocale: 'en',
  fallback: true,
}
```

## Deployment

### Vercel Deployment
This project is configured for Vercel deployment:
- PostgreSQL: Use Vercel Postgres or external database
- Environment variables: Configure in Vercel dashboard
- Build command: `pnpm build`
- Output directory: `.next`
- Install command: `pnpm install`

### Manual Deployment
1. Build project: `pnpm build`
2. Run migrations: `pnpm payload migrate`
3. Start server: `pnpm start`
4. Configure reverse proxy (nginx) to point to port 3000
5. Use PM2 or similar for process management

## Resources

- [Payload CMS Docs](https://payloadcms.com/docs)
- [Next.js App Router Docs](https://nextjs.org/docs/app)
- [Project Setup Guide](./OGB_SETUP_GUIDE.md) - Detailed setup instructions
- [Related Project](../daemez.solutions) - Reference for advanced features
