Files
pantry/CLAUDE.md
Eric Wagoner 08d550b0bd Update documentation with all features and learnings
- Updated README with all features: spices filter, shopping list export,
  clickable container legend, category prefixes
- Added deployment troubleshooting for file ownership issues
- Updated CLAUDE.md with architecture details, filtering logic,
  common issues and fixes
- Added live URL reference

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 22:23:23 -05:00

4.0 KiB

CLAUDE.md

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

Project Overview

Pantry is a simple web app for tracking kitchen pantry items. It's a single-page application with no build step.

Live URL: https://pantry.kestrelsnest.social

File Structure

  • index.html - Frontend (HTML/CSS/JS all in one file)
  • api.php - Backend API (JSON file-based storage)
  • containers.json - Container type definitions with categories
  • og-image.png - OpenGraph image for social sharing
  • deploy - Rsync deployment script

Architecture

Frontend (index.html):

  • Vanilla JavaScript, no frameworks
  • Uses QRCode.js from CDN for QR code generation
  • Custom CSS with CSS variables for theming (earthy color palette: cream, terracotta, forest green)
  • Container types loaded from containers.json at startup into containerTypes object
  • All API calls go through the apiCall() function which POSTs to api.php

Backend (api.php):

  • JSON file-based storage in data/ directory
  • Endpoints: get, add, update, delete, setPin, verifyPin
  • sanitize() function only trims whitespace - do NOT add HTML encoding (causes double-encoding issues)

Container Configuration (containers.json):

  • Defines container types organized by category
  • Each container has: id, name, color
  • Categories have: name, containers[]
  • Frontend displays as "Category: Container Name" (e.g., "Glass Spice Jars: Hex (Large)")

Data Storage:

  • data/inventory.json - Inventory items
  • data/pin.txt - 4-digit PIN for edit mode (plain text)
  • data/ directory must be owned by web server user (my_webapp__2), not admin user

Development

This is a no-build project. To test locally:

php -S localhost:8000

Then open http://localhost:8000 in a browser.

Deployment

The deploy script uses rsync to push to YunoHost:

# Deploy code, pull data from server
./deploy

# Deploy code AND push local data to server
./deploy --reset-data

Important deployment notes:

  • Files in data/ must be owned by the web server user (my_webapp__2) for PHP to write to them
  • If deploying with --reset-data, the uploaded files get admin ownership - the web server then can't edit them
  • Fix with: sudo chown my_webapp__2:my_webapp__2 /var/www/my_webapp__2/www/data/inventory.json
  • Adding admin to the my_webapp__2 group allows the deploy script to write while keeping web server access

Key Implementation Details

Data model:

  • Items have: id, name, container (type ID), outOfStock (boolean)

Filtering:

  • currentFilter - Tab filter: 'all', 'in-stock', 'out', 'spices', 'qr'
  • containerFilter - Container type filter (null or container ID), set by clicking legend items
  • Both filters combine with search text

Container legend:

  • Clickable - filters inventory by that container type
  • Shows count of items per container type
  • Active filter highlighted in forest green

Shopping list:

  • Tap "Out of Stock" stat to copy all out-of-stock item names to clipboard
  • Sorted alphabetically, one per line

UI patterns:

  • renderInventory() - Re-renders the item list
  • renderContainerLegend() - Re-renders legend with counts, called from updateStats()
  • showToast(message) - Shows temporary notification
  • escapeHtml(text) - Escapes text for safe HTML display (used on item names)

Common Issues

Apostrophes/special characters showing as HTML entities:

  • Caused by double-encoding: API was using htmlspecialchars() AND frontend uses escapeHtml()
  • Fix: sanitize() in api.php should only trim(), not HTML-encode
  • Affected items need to be re-saved through UI

Edits not saving:

  • Usually file ownership issue - web server can't write to files owned by admin
  • Check ownership of data/inventory.json

OpenGraph

Meta tags in <head> point to og-image.png at:

  • https://pantry.kestrelsnest.social/og-image.png

If URL changes, update the og:image and twitter:image meta tags.