chore: Add CLAUDE.md, TODO.md, and fix ReadBooks Tailwind classes
- Add CLAUDE.md with project architecture, conventions, and common tasks - Add TODO.md with prioritized roadmap (book reviews, CMS, n8n, frontend) - Fix invalid Tailwind classes in ReadBooks.tsx (h-30 -> h-[7.5rem], w-22 -> w-24) https://claude.ai/code/session_017E8W9CcHFM5WQVHw74JP34
This commit is contained in:
155
CLAUDE.md
Normal file
155
CLAUDE.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# CLAUDE.md - Portfolio Project Guide
|
||||
|
||||
## Project Overview
|
||||
|
||||
Personal portfolio website for Dennis Konkol (dk0.dev). Built with Next.js 15 (App Router), TypeScript, Tailwind CSS, and Framer Motion. Uses a "liquid" design system with soft gradient colors and glassmorphism effects.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Framework**: Next.js 15 (App Router), TypeScript 5.9
|
||||
- **Styling**: Tailwind CSS 3.4 with custom `liquid-*` color tokens
|
||||
- **Animations**: Framer Motion 12
|
||||
- **3D**: Three.js + React Three Fiber (shader gradient background)
|
||||
- **Database**: PostgreSQL via Prisma ORM
|
||||
- **Cache**: Redis (optional)
|
||||
- **CMS**: Directus (self-hosted, REST/GraphQL, optional)
|
||||
- **Automation**: n8n webhooks (status, chat, hardcover, image generation)
|
||||
- **i18n**: next-intl (EN + DE), message files in `messages/`
|
||||
- **Monitoring**: Sentry
|
||||
- **Deployment**: Docker + Nginx, CI via Gitea Actions
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
npm run dev # Full dev environment (Docker + Next.js)
|
||||
npm run dev:simple # Next.js only (no Docker)
|
||||
npm run dev:next # Plain Next.js dev server
|
||||
npm run build # Production build
|
||||
npm run lint # ESLint
|
||||
npm run test # Jest unit tests
|
||||
npm run test:e2e # Playwright E2E tests
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
app/
|
||||
[locale]/ # i18n routes (en, de)
|
||||
page.tsx # Homepage (hero, about, projects, contact)
|
||||
projects/ # Project listing + detail pages
|
||||
api/ # API routes
|
||||
book-reviews/ # Book reviews from Directus CMS
|
||||
content/ # CMS content pages
|
||||
hobbies/ # Hobbies from Directus
|
||||
n8n/ # n8n webhook proxies
|
||||
hardcover/ # Currently reading (Hardcover API via n8n)
|
||||
status/ # Activity status (coding, music, gaming)
|
||||
chat/ # AI chatbot
|
||||
generate-image/ # AI image generation
|
||||
projects/ # Projects API (PostgreSQL + Directus fallback)
|
||||
tech-stack/ # Tech stack from Directus
|
||||
components/ # React components
|
||||
About.tsx # About section (tech stack, hobbies, books)
|
||||
CurrentlyReading.tsx # Currently reading widget (n8n/Hardcover)
|
||||
ReadBooks.tsx # Read books with ratings (Directus CMS)
|
||||
Projects.tsx # Featured projects section
|
||||
Hero.tsx # Hero section
|
||||
Contact.tsx # Contact form
|
||||
lib/
|
||||
directus.ts # Directus GraphQL client (no SDK)
|
||||
auth.ts # Auth utilities + rate limiting
|
||||
prisma/
|
||||
schema.prisma # Database schema
|
||||
messages/
|
||||
en.json # English translations
|
||||
de.json # German translations
|
||||
docs/ # Documentation
|
||||
```
|
||||
|
||||
## Architecture Patterns
|
||||
|
||||
### Data Source Hierarchy (Fallback Chain)
|
||||
1. Directus CMS (if configured via `DIRECTUS_STATIC_TOKEN`)
|
||||
2. PostgreSQL (for projects, analytics)
|
||||
3. JSON files (`messages/*.json`)
|
||||
4. Hardcoded defaults
|
||||
5. Display key itself as last resort
|
||||
|
||||
All external data sources fail gracefully - the site never crashes if Directus, PostgreSQL, n8n, or Redis are unavailable.
|
||||
|
||||
### CMS Integration (Directus)
|
||||
- REST/GraphQL calls via `lib/directus.ts` (no Directus SDK)
|
||||
- Collections: `tech_stack_categories`, `tech_stack_items`, `hobbies`, `content_pages`, `projects`, `book_reviews`
|
||||
- Translations use Directus native translation system (M2O to `languages`)
|
||||
- Locale mapping: `en` -> `en-US`, `de` -> `de-DE`
|
||||
|
||||
### n8n Integration
|
||||
- Webhook base URL: `N8N_WEBHOOK_URL` env var
|
||||
- Auth via `N8N_SECRET_TOKEN` and/or `N8N_API_KEY` headers
|
||||
- All n8n endpoints have rate limiting and timeout protection (10s)
|
||||
- Hardcover data cached for 5 minutes
|
||||
|
||||
### Component Patterns
|
||||
- Client components with `"use client"` for interactive/data-fetching parts
|
||||
- `useEffect` for data loading on mount
|
||||
- `useTranslations` from next-intl for i18n
|
||||
- Framer Motion `variants` pattern with `staggerContainer` + `fadeInUp`
|
||||
- Gradient cards with `liquid-*` color tokens and `backdrop-blur-sm`
|
||||
|
||||
## Design System
|
||||
|
||||
Custom Tailwind colors prefixed with `liquid-`:
|
||||
- `liquid-sky`, `liquid-mint`, `liquid-lavender`, `liquid-pink`
|
||||
- `liquid-rose`, `liquid-peach`, `liquid-coral`, `liquid-teal`, `liquid-lime`
|
||||
|
||||
Cards use gradient backgrounds (`bg-gradient-to-br from-liquid-*/15 via-liquid-*/10 to-liquid-*/15`) with `border-2` and `rounded-xl`.
|
||||
|
||||
## Key Environment Variables
|
||||
|
||||
```bash
|
||||
# Required for CMS
|
||||
DIRECTUS_URL=https://cms.dk0.dev
|
||||
DIRECTUS_STATIC_TOKEN=...
|
||||
|
||||
# Required for n8n features
|
||||
N8N_WEBHOOK_URL=https://n8n.dk0.dev
|
||||
N8N_SECRET_TOKEN=...
|
||||
N8N_API_KEY=...
|
||||
|
||||
# Database
|
||||
DATABASE_URL=postgresql://...
|
||||
|
||||
# Optional
|
||||
REDIS_URL=redis://...
|
||||
SENTRY_DSN=...
|
||||
```
|
||||
|
||||
## Conventions
|
||||
|
||||
- Language: Code in English, user-facing text via i18n (EN + DE)
|
||||
- Commit messages: Conventional Commits (`feat:`, `fix:`, `chore:`)
|
||||
- Components: PascalCase files in `app/components/`
|
||||
- API routes: kebab-case directories in `app/api/`
|
||||
- CMS data always has a static fallback - never rely solely on Directus
|
||||
- Error logging: Only in `development` mode (`process.env.NODE_ENV === "development"`)
|
||||
- No emojis in code unless explicitly requested
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Adding a new CMS-managed section
|
||||
1. Define the GraphQL query + types in `lib/directus.ts`
|
||||
2. Create an API route in `app/api/<name>/route.ts`
|
||||
3. Create a component in `app/components/<Name>.tsx`
|
||||
4. Add i18n keys to `messages/en.json` and `messages/de.json`
|
||||
5. Integrate into the parent component (usually `About.tsx`)
|
||||
|
||||
### Adding i18n strings
|
||||
1. Add keys to `messages/en.json` and `messages/de.json`
|
||||
2. Access via `useTranslations("key.path")` in client components
|
||||
3. Or `getTranslations("key.path")` in server components
|
||||
|
||||
### Working with Directus collections
|
||||
- All queries go through `directusRequest()` in `lib/directus.ts`
|
||||
- Uses GraphQL endpoint (`/graphql`)
|
||||
- 2-second timeout, graceful null fallback
|
||||
- Translations filtered by `languages_code.code` matching Directus locale
|
||||
Reference in New Issue
Block a user