This file provides guidance to Claude Code (claude.ai/code) or similar agents when working with code in this repository.
Frank's Book Log is an Astro-based static site for book reviews and reading tracking. Built with TypeScript, React components, and Tailwind CSS. The site uses a content-first architecture with JSON data files and Markdown reviews.
# Development
npm run dev # Start dev server on localhost:4321
npm start # Alias for dev
# Building
npm run build # Build for production
npm run preview # Preview production build
# Testing
npm run test -- --max-workers=2 # Run all tests
npm run test:coverage -- --max-workers=2 # Run tests with coverage report
# Code Quality
npm run lint # Run ESLint
npm run lint:fix # Fix ESLint issues
npm run format # Check Prettier formatting
npm run format:fix # Fix formatting issues
npm run stylelint # Run Stylelint on CSS
npm run stylelint:fix # Fix Stylelint issues
npm run check # Astro type checking
npm run knip # Check for unused dependencies/exports
# Content Management
npm run sync # Sync content from backend system/content/- All content data (JSON and Markdown), kept separate from code/data/- JSON data files with Zod validation schemas/reading-log/- Complete reading history/reviewed-authors/- Authors with reviewed works/reviewed-works/- Reviewed works/year-stats/- Reading stats per yearall-time-stats.json- All-time reading stats
/reviews/- Markdown review files/readings/- Reading history entries/assets/- Images (covers, avatars, backdrops)
- All collection definitions, loaders, and schemas.
- Main configuration file located at
/src/content.config.ts(mandated by Astro)
Features (/src/features/):
- Page features organized by domain (e.g.,
author/,reviews/,readings/,stats/) - Each feature contains:
Component.tsx- Main feature componentComponent.spec.tsx- Tests (Vitest + Testing Library)getProps.ts- Props building for React componentsComponent.reducer.ts- State management for complex interactions- Additional feature-specific components (e.g.,
Filters.tsx,OpenGraphImage.tsx)
Shared Components (/src/components/):
- Reusable UI components organized by functionality:
/fields/- Form inputs (SelectField, TextField, YearField, etc.)/applied-filters/-AppliedFilterscomponent (exportsFilterChiptype too)/collection-filters/-CollectionFilterscomponent +CollectionSortOptionsconstant + test helper/filter-and-sort-container/-FilterAndSortContainercomponent + header/section privates + test helper/reviewed-status-filter/-ReviewedStatusFiltercomponent + test helper/reviewed-work-filters/-ReviewedWorkFilterscomponent +ReviewedWorkSortOptionsconstant + test helper/work-filters/-WorkFilterscomponent + test helper/layout/- Layout components (Header, Footer, Navigation)/cover-list/,/avatar-list/- Content display components- Other shared utilities (Grade, Cover, Avatar, etc.)
Tests run in jsdom environment for React components.
Important: Run only one Vitest instance at a time. Each instance consumes ~2GB RAM, so avoid spawning multiple test processes simultaneously.
~/maps tosrc/directory
- The purpose of tests is to tell me two things:
- Will this dependency update break the site?
- Will this change cause other, unintended changes?
- Testing focuses on the interactive React components:
- Exercise interactive elements like a user
- Goal: By exercising all options and rendering all permutations, any uncovered code must be dead code safe to remove
-
IMPORTANT: Always create a new feature branch for new features:
git checkout -b feat/feature-namefor featuresgit checkout -b fix/bug-namefor bug fixesgit checkout -b chore/task-namefor maintenance tasks
-
IMPORTANT: Always rebase on origin/main before pushing:
git pull --rebase origin main
-
Make changes with proper types
-
Run tests and linting
-
IMPORTANT: Before creating any PR, run:
-
npm run test- Must pass with no errors -
npm run lint- Must pass with no errors -
npm run check- Must pass with no errors -
npm run knip- Must pass with no errors -
npm run format- Must pass with no errors -
This ensures your PR is based on the latest code
-
-
Create PR with descriptive title
-
Ensure all CI checks pass
- IMPORTANT: When running test or test:coverage, make sure and run with max-workers=2
- Don't use the
anytype. The linter will error on it. - Use TypeScript types, not JSDoc types: When functions have TypeScript type annotations, avoid duplicate type information in JSDoc comments. Use
@param name - descriptioninstead of@param {Type} name - description. Keep the descriptive text but remove type annotations in curly braces.