Files
basil/CLAUDE.md
Paul R Kartchner d1156833a2
Some checks failed
CI/CD Pipeline / Run Tests (pull_request) Has been cancelled
CI/CD Pipeline / Code Quality (pull_request) Has been cancelled
CI Pipeline / Lint Code (pull_request) Has been cancelled
CI Pipeline / Test API Package (pull_request) Has been cancelled
CI Pipeline / Test Web Package (pull_request) Has been cancelled
CI Pipeline / Test Shared Package (pull_request) Has been cancelled
Docker Build & Deploy / Build Docker Images (pull_request) Has been cancelled
E2E Tests / End-to-End Tests (pull_request) Has been cancelled
E2E Tests / E2E Tests (Mobile) (pull_request) Has been cancelled
Security Scanning / NPM Audit (pull_request) Has been cancelled
Security Scanning / Dependency License Check (pull_request) Has been cancelled
Security Scanning / Code Quality Scan (pull_request) Has been cancelled
Security Scanning / Docker Image Security (pull_request) Has been cancelled
CI/CD Pipeline / Build and Push Docker Images (pull_request) Has been cancelled
CI Pipeline / Build All Packages (pull_request) Has been cancelled
CI Pipeline / Generate Coverage Report (pull_request) Has been cancelled
Docker Build & Deploy / Push Docker Images (pull_request) Has been cancelled
Docker Build & Deploy / Deploy to Staging (pull_request) Has been cancelled
Docker Build & Deploy / Deploy to Production (pull_request) Has been cancelled
Security Scanning / Security Summary (pull_request) Has been cancelled
feat: add CI/CD pipeline, backup system, and deployment automation
## Summary
- Add complete CI/CD pipeline with Gitea Actions for automated testing, building, and deployment
- Implement backup and restore system with full database and file backup to ZIP
- Add deployment automation with webhook receiver and systemd service
- Enhance recipe editing UI with improved ingredient parsing and cooking mode features
- Add comprehensive documentation for CI/CD, deployment, and backup features

## CI/CD Pipeline
- New workflow in .gitea/workflows/ci-cd.yml with test, build, and deploy stages
- Automated Docker image building and pushing to registry
- Webhook-triggered deployments to production servers

## Backup & Restore
- New backup service with ZIP creation including database dump and uploads
- REST API endpoints for create, list, download, restore, and delete operations
- Configurable backup path via BACKUP_PATH environment variable

## Deployment
- Automated deployment scripts (deploy.sh, manual-deploy.sh)
- Webhook receiver with systemd service for deployment triggers
- Environment configuration template (.env.deploy.example)

## Documentation
- docs/CI-CD-SETUP.md - Complete CI/CD pipeline setup guide
- docs/DEPLOYMENT-QUICK-START.md - Quick deployment reference
- docs/BACKUP.md - Backup and restore documentation
- docs/REMOTE_DATABASE.md - Remote database configuration guide
- scripts/README.md - Deployment scripts documentation

## Web Improvements
- Enhanced ingredient parser with better unit and quantity detection
- Improved recipe editing interface with unified edit experience
- Better cooking mode functionality
- Updated dependencies in package.json

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 05:04:39 +00:00

273 lines
9.2 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Basil is a full-stack recipe manager built with TypeScript. It features a REST API backend, React web frontend, and PostgreSQL database. The application supports importing recipes from URLs via schema.org markup parsing, local/S3 image storage, and comprehensive recipe management (CRUD operations, search, tagging).
## Architecture
**Monorepo Structure:**
- `packages/shared/` - Shared TypeScript types and interfaces used across all packages
- `packages/api/` - Express.js REST API server with Prisma ORM
- `packages/web/` - React + Vite web application
- Future: `packages/mobile/` - React Native mobile apps
**Key Technologies:**
- Backend: Node.js, TypeScript, Express, Prisma ORM, PostgreSQL
- Frontend: React, TypeScript, Vite, React Router
- Infrastructure: Docker, Docker Compose, nginx
- Recipe Scraping: Cheerio for HTML parsing, Schema.org Recipe markup support
**Database Schema:**
- `Recipe` - Main recipe entity with metadata (prep/cook time, servings, ratings)
- `Ingredient` - Recipe ingredients with amounts, units, and ordering
- `Instruction` - Step-by-step instructions with optional images
- `RecipeImage` - Multiple images per recipe
- `Tag` / `RecipeTag` - Many-to-many tagging system
**Storage Architecture:**
- Primary: Local filesystem storage (`./uploads`)
- Optional: S3 storage (configurable via environment variables)
- Storage service implements strategy pattern for easy switching
## Development Commands
```bash
# Install all dependencies (root + all packages)
npm install
# Development mode (starts all packages with hot reload)
npm run dev
# Build all packages
npm run build
# Lint all packages
npm run lint
# Testing
npm test # Run all unit tests
npm run test:e2e # Run E2E tests with Playwright
npm run test:e2e:ui # Run E2E tests with Playwright UI
# Docker commands
npm run docker:up # Start all services (PostgreSQL, API, web)
npm run docker:down # Stop all services
npm run docker:build # Rebuild Docker images
```
### Backend-Specific Commands
```bash
cd packages/api
# Development with auto-reload
npm run dev
# Database migrations
npm run prisma:migrate # Create and apply migration
npm run prisma:generate # Generate Prisma client
npm run prisma:studio # Open Prisma Studio GUI
# Build for production
npm run build
npm start
```
### Frontend-Specific Commands
```bash
cd packages/web
# Development server
npm run dev
# Production build
npm run build
npm run preview # Preview production build locally
```
## Configuration
**Environment Variables (packages/api/.env):**
```
PORT=3001
NODE_ENV=development
DATABASE_URL=postgresql://basil:basil@localhost:5432/basil?schema=public
STORAGE_TYPE=local # or 's3'
LOCAL_STORAGE_PATH=./uploads
BACKUP_PATH=./backups
CORS_ORIGIN=http://localhost:5173
```
For S3 storage, add:
```
S3_BUCKET=basil-recipes
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=your-key
S3_SECRET_ACCESS_KEY=your-secret
```
For remote PostgreSQL database, update:
```
DATABASE_URL=postgresql://username:password@remote-host:5432/basil?schema=public
```
## Key Features
### Recipe Import from URL
- `POST /api/recipes/import` - Scrapes recipe from URL using schema.org markup
- Extracts: title, description, ingredients, instructions, times, images
- Handles JSON-LD structured data (primary) with fallback to manual parsing
- Downloads and stores images locally or on S3
### Recipe Management
- Full CRUD operations on recipes
- Pagination and search (by title, description)
- Filtering by cuisine, category
- Image upload with multiple images per recipe
- Tagging system for organization
### Storage Service
- Abstracted storage interface in `packages/api/src/services/storage.service.ts`
- Local storage: Saves to filesystem with timestamped filenames
- S3 storage: Placeholder for AWS SDK implementation
- Easy to extend for other storage providers
### Backup & Restore
- Complete data backup to single ZIP file including database and uploaded files
- Backup service in `packages/api/src/services/backup.service.ts`
- REST API for creating, listing, downloading, and restoring backups
- Automatic backup of all recipes, cookbooks, tags, and relationships
- Configurable backup storage location via `BACKUP_PATH` environment variable
## Adding New Features
### Adding a New API Endpoint
1. Add route handler in `packages/api/src/routes/*.routes.ts`
2. Update shared types in `packages/shared/src/types.ts` if needed
3. Rebuild shared package: `cd packages/shared && npm run build`
4. Use Prisma client for database operations
### Adding a New Frontend Page
1. Create component in `packages/web/src/pages/`
2. Add route in `packages/web/src/App.tsx`
3. Create API service methods in `packages/web/src/services/api.ts`
4. Import and use shared types from `@basil/shared`
### Database Schema Changes
1. Edit `packages/api/prisma/schema.prisma`
2. Run `npm run prisma:migrate` to create migration
3. Run `npm run prisma:generate` to update Prisma client
4. Update TypeScript types in `packages/shared/src/types.ts` to match
## Docker Deployment
The project includes full Docker support for production deployment:
```bash
docker-compose up -d
```
This starts:
- PostgreSQL database (port 5432)
- API server (port 3001)
- Web frontend served via nginx (port 5173)
Persistent volumes:
- `postgres_data` - Database storage
- `uploads_data` - Uploaded images
- `backups_data` - Backup files
### Using a Remote Database
To use a remote PostgreSQL database instead of the local Docker container:
1. Set the `DATABASE_URL` environment variable to point to your remote database
2. Update `docker-compose.yml` to pass the environment variable or create a `.env` file in the root
3. Optionally, remove or comment out the `postgres` service and its dependency in `docker-compose.yml`
Example `.env` file in project root:
```
DATABASE_URL=postgresql://username:password@remote-host:5432/basil?schema=public
```
The docker-compose.yml is configured to use `${DATABASE_URL:-default}` which will use the environment variable if set, or fall back to the local postgres container.
## API Reference
**Recipes:**
- `GET /api/recipes` - List all recipes (supports pagination, search, filters)
- `GET /api/recipes/:id` - Get single recipe with all relations
- `POST /api/recipes` - Create new recipe
- `PUT /api/recipes/:id` - Update recipe
- `DELETE /api/recipes/:id` - Delete recipe and associated images
- `POST /api/recipes/:id/images` - Upload image for recipe
- `POST /api/recipes/import` - Import recipe from URL
**Query Parameters:**
- `page`, `limit` - Pagination
- `search` - Search in title/description
- `cuisine`, `category` - Filter by cuisine or category
**Backups:**
- `POST /api/backup` - Create a new backup (returns backup metadata)
- `GET /api/backup` - List all available backups
- `GET /api/backup/:filename` - Download a specific backup file
- `POST /api/backup/restore` - Restore from backup (accepts file upload or existing filename)
- `DELETE /api/backup/:filename` - Delete a backup file
## Important Implementation Details
### Prisma Relations
- All related entities (ingredients, instructions, images, tags) use cascade delete
- Ingredients and instructions maintain ordering via `order` and `step` fields
- Tags use many-to-many relationship via `RecipeTag` join table
### Recipe Scraping
- Primary: Parses JSON-LD `application/ld+json` scripts for Schema.org Recipe data
- Fallback: Extracts basic info from HTML meta tags and headings
- Handles ISO 8601 duration format (PT30M, PT1H30M) for cook times
- Downloads images asynchronously and stores them locally
### Frontend Routing
- Uses React Router v6 for client-side routing
- Vite proxy forwards `/api` and `/uploads` requests to backend during development
- Production uses nginx reverse proxy to backend API
### TypeScript Workspace
- Root `package.json` defines npm workspaces
- Packages can reference each other (e.g., `@basil/shared`)
- Must rebuild shared package when types change for other packages to see updates
## CI/CD and Deployment
Basil includes a complete CI/CD pipeline with Gitea Actions for automated testing, building, and deployment.
**Quick Start:**
- See [CI/CD Setup Guide](docs/CI-CD-SETUP.md) for full documentation
- See [Deployment Quick Start](docs/DEPLOYMENT-QUICK-START.md) for quick reference
**Pipeline Overview:**
1. **Test Stage**: Runs unit tests (Vitest) and E2E tests (Playwright)
2. **Build Stage**: Builds Docker images for API and Web (main branch only)
3. **Deploy Stage**: Pushes images to registry and triggers webhook deployment
**Deployment Options:**
- **Automatic**: Push to main branch triggers full CI/CD pipeline
- **Manual**: Run `./scripts/manual-deploy.sh` for interactive deployment
- **Webhook**: Systemd service listens for deployment triggers
**Key Files:**
- `.gitea/workflows/ci-cd.yml` - Main CI/CD workflow
- `scripts/deploy.sh` - Deployment script
- `scripts/webhook-receiver.sh` - Webhook server
- `.env.deploy.example` - Deployment configuration template
**Required Secrets (Gitea):**
- `DOCKER_USERNAME` - Docker Hub username
- `DOCKER_PASSWORD` - Docker Hub access token
- `DEPLOY_WEBHOOK_URL` - Webhook endpoint for deployments