3.4 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Parsley is a personal recipe manager and meal planning app. It is a monolithic Rails 7.2 application with a Vue 3 SPA frontend.
Backend: Ruby 4.0.2, Rails 8.1.3, SQLite (dev/test), PostgreSQL (production)
Frontend: Vue 3 (Composition API / <script setup>), Pinia, Vue Router 4, Bulma CSS
Asset bundling: Shakapacker 8 (Webpack 5 + SWC)
Testing: RSpec, FactoryBot, Guard
Common Commands
# Development
foreman start # Start Rails + Shakapacker dev server together
# Dependencies
bundle install && yarn install
# Database
bundle exec rake db:create db:migrate db:seed
bundle exec rake db:reset # Drop, recreate, seed
# Tests
bundle exec rspec # All tests
bundle exec rspec spec/models/recipe_spec.rb # Single file
bundle exec rspec spec/models/recipe_spec.rb:42 # Single test by line
bundle exec guard # Watch mode
# Build
bundle exec rake shakapacker:compile # Compile assets for production
Test environment note: Set FAST=true to skip FactoryBot linting on startup.
Architecture
Backend
Models follow an Ingredient abstraction: Recipe and Food both inherit from an abstract Ingredient base class. This allows recipes to contain both foods and other recipes as ingredients (RecipeIngredient is a polymorphic join). Polymorphic ingredient IDs are encoded as strings: F{id} for foods, R{id} for recipes.
Custom unit conversion library (lib/unit_conversion/): The UnitConversion module handles all quantity parsing and conversion. It is density-aware (can convert volume ↔ mass if food density is known) and supports custom per-food units defined in FoodUnit records. Key entry points: UnitConversion.parse, UnitConversion.auto_unit, UnitConversion.with_custom_units.
Recipe scaling: Recipes can be scaled by a factor and converted between unit systems (standard/metric) and unit types (mass/volume). Cache keys incorporate scale and unit system: recipes/{id}/{scale}/{system}/{unit}. Memcache is optional; enable with RAILS_USE_MEMCACHE=true.
USDA nutrition data: The UsdaImporter (lib/) imports from vendor/data/usda/ during db:seed. UsdaFood/UsdaFoodWeight tables are a read-only cache; Food records link to them and inherit nutritional data.
Serializers (app/serializers/) handle all JSON API responses.
Frontend
Vue 3 components live in app/javascript/components/. They use <script setup> Composition API style. Pinia stores (app/javascript/stores/) hold global state. Vue Router (app/javascript/router/) manages navigation.
Page-level components are named The* (e.g., TheRecipeList, TheFood, TheCalculator). Shared UI primitives are named App* (e.g., AppModal, AppAutocomplete, AppIcon).
Key Environment Variables
| Variable | Purpose |
|---|---|
RAILS_USE_MEMCACHE |
Enable Memcache caching |
RAILS_MEMCACHE_HOST |
Memcache host (default: memcache) |
PARSLEY_DB_HOST/USER/PG_PASSWORD/DB_NAME |
Production PostgreSQL config |
Docker
docker-compose up starts PostgreSQL, Memcached, Nginx, and two Rails service instances. See docker-compose.yml and Dockerfile.
Seed Data
Default dev user: username dan, password qwerty. Comes with sample recipes and foods.