MyRecipeBox PWA

A Progressive Web Application for collecting, organizing, and accessing recipes both online and offline. Features AI-powered recipe extraction from URLs and images, comprehensive search functionality, and role-based access control.

๐Ÿš€ Features

  • Progressive Web App with offline functionality
  • AI-Powered Recipe Extraction from URLs and images using Google Gemini API
  • Triple Input Methods (URL, manual form, and image upload with OCR)
  • Recipe Publishing System with draft/published states and role-based visibility
  • Advanced Search & Tagging system
  • Role-Based Access Control (Admin/Reader) with granular permissions
  • Offline-First Architecture with smart caching
  • Material Design with theme support and visual indicators

๐Ÿ“‹ Development Progress

โœ… Phase 1: Core Foundation & Setup

  • Set up SvelteKit project with TypeScript
  • Install dependencies (PocketBase SDK, Dexie, Gemini API)
  • Create project folder structure
  • Configure environment variables
  • Define TypeScript interfaces and data models
  • Create service classes for API interactions
  • Set up Svelte stores for state management
  • Set up PocketBase backend with collections
  • Create development scripts and environment

โœ… Phase 2: Authentication & Authorization

  • Implement PocketBase authentication
  • Create login/register components with Svelte 5 runes
  • Set up OAuth providers (Google, GitHub)
  • Implement role-based access control
  • Create authentication guards and navigation
  • Write comprehensive unit and E2E tests
  • Update components to use modern Svelte 5 syntax

โœ… Phase 3: Recipe Management

  • Build manual recipe creation form with comprehensive validation
  • Implement recipe CRUD operations with PocketBase integration
  • Create recipe listing and detail views with responsive design
  • Add admin-only edit/delete functionality with role-based access
  • Create admin routes (/admin/recipes/new, /admin/recipes/[id]/edit)
  • Implement recipe detail view (/recipes/[id]) with breadcrumbs
  • Update homepage to display recipe collection
  • Add comprehensive E2E tests with test IDs and CSS classes
  • Fix registration bug (passwordConfirm field missing)
  • Update E2E tests to use real PocketBase instead of mocks
  • Set up interactive coverage UI with Vitest
  • Implement recipe publishing system with draft/published states
  • Add role-based recipe visibility (admin sees all, readers see published only)
  • Create draft indicators and visual badges for unpublished recipes
  • Add publish toggle in recipe creation and editing forms
  • Implement proper error handling with custom error pages

โœ… Phase 4: AI Integration

  • Integrate Google Gemini API for URL extraction
  • Implement image upload and preprocessing
  • Add Gemini Vision API for OCR capabilities
  • Create review/edit interface for extracted content
  • Build comprehensive extraction UI with three modes (manual, URL, image)
  • Add API endpoints for server-side extraction processing
  • Implement proper error handling and validation

โœ… Phase 5: Search & Discovery

  • Implement advanced search functionality with multiple filter options
  • Create dedicated search page (/search) with comprehensive filtering
  • Build tag management interface for administrators (/admin/tags)
  • Add popular tags display and quick filtering on homepage
  • Enhanced navigation with search functionality in header
  • Integrate cuisine, difficulty, and dietary preference filters
  • Add real-time search with auto-complete functionality
  • Create tag-based filtering with visual tag indicators

๐Ÿ“‹ Phase 6: PWA & Offline Features

  • Implement caching strategy with service workers
  • Add offline data synchronization
  • Configure PWA manifest and installation
  • Handle offline/online state transitions

๐Ÿ“‹ Phase 7: Testing & Quality

  • Write unit tests for all components
  • Create integration tests with Playwright
  • Test authentication and authorization
  • Test AI extraction features
  • Test offline functionality

๐Ÿ“‹ Phase 8: Deployment & Production

  • Docker deployment with custom PocketBase v0.29.0
  • Production-ready Docker Compose configuration
  • Multi-stage frontend build with Node.js adapter
  • Environment variable configuration for production
  • Health checks and container orchestration
  • Configure Cloudflare Pages deployment
  • Set up CI/CD pipeline
  • Add error tracking and monitoring
  • Performance optimization

๐Ÿ›  Tech Stack

  • Frontend: SvelteKit with TypeScript
  • Backend: PocketBase v0.29.0 (SQLite/PostgreSQL)
  • Authentication: PocketBase Auth (OAuth2, email/password)
  • AI Integration: Google Gemini API (text & vision)
  • Styling: Tailwind CSS with forms and typography plugins
  • Offline Storage: Dexie.js (IndexedDB wrapper)
  • Testing: Vitest (unit/component) + Playwright (E2E)
  • Deployment: Docker Compose with custom PocketBase v0.29.0

๐Ÿ“ Recipe Publishing System

Publishing States

  • Published: Recipes visible to all authenticated users (admin and readers)
  • Draft: Recipes only visible to admin users who created them

Role-Based Visibility

  • Admin Users: Can see all recipes (published and drafts) and manage publishing status
  • Reader Users: Can only see published recipes, no access to drafts

Visual Indicators

  • Draft Badge: Yellow "Draft" indicator appears on unpublished recipe cards (admin view only)
  • Publishing Toggle: Checkbox in recipe creation/edit forms to control published status
  • Error Pages: Custom error handling for invalid recipe access

Features

  • โœ… Publish Toggle: Easy one-click publishing from recipe forms
  • โœ… Draft Management: Create and refine recipes before publishing
  • โœ… Role-Based Access: Automatic filtering based on user permissions
  • โœ… Visual Feedback: Clear indicators for recipe status
  • โœ… Error Handling: Graceful handling of access denied scenarios

๐Ÿš€ Getting Started

Prerequisites

  • Node.js 22.x (managed with asdf)
  • npm 10.x

Installation

  1. Clone the repository

  2. Install dependencies:

    npm install
  3. Set up environment variables:

    cp .env.example .env
    # Edit .env with your configuration
  4. Start the development server:

    npm run dev

Development Commands

# Development server
npm run dev

# Run tests
npm run test

# Run unit tests only
npm run test:unit

# Run E2E tests
npm run test:e2e

# Build for production
npm run build

# Preview production build
npm run preview

# Lint and format code
npm run lint
npm run format

๐Ÿ“š Project Structure

src/
โ”œโ”€โ”€ lib/
โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”œโ”€โ”€ ui/          # Reusable UI components
โ”‚   โ”‚   โ”œโ”€โ”€ forms/       # Form components
โ”‚   โ”‚   โ”œโ”€โ”€ recipe/      # Recipe-specific components
โ”‚   โ”‚   โ”œโ”€โ”€ auth/        # Authentication components
โ”‚   โ”‚   โ””โ”€โ”€ layout/      # Layout components
โ”‚   โ”œโ”€โ”€ stores/          # Svelte stores for state management
โ”‚   โ”œโ”€โ”€ services/        # API services and business logic
โ”‚   โ”œโ”€โ”€ types/           # TypeScript type definitions
โ”‚   โ””โ”€โ”€ utils/           # Utility functions
โ”œโ”€โ”€ routes/              # SvelteKit routes
โ””โ”€โ”€ tests/               # Test files

๐Ÿ”ง Configuration

Environment Variables

See .env.example for all required environment variables.

PocketBase Setup

  1. Install PocketBase
  2. Run PocketBase server
  3. Configure collections and authentication
  4. Set up admin user

๐Ÿงช Testing

This project follows a comprehensive testing strategy with multiple test types and tools to ensure reliability and quality.

Test Types & Coverage

  • Unit Tests: Service layer logic, store management, utility functions
  • Component Tests: Svelte component rendering and interactions
  • E2E Tests: Complete user journeys and authentication flows
  • Integration Tests: API interactions and cross-component workflows

Testing Stack

  • Vitest - Unit and component testing framework
  • Playwright - End-to-end testing with real browsers
  • Testing Library - Component testing utilities and DOM queries
  • jsdom - DOM simulation for unit tests

Running Tests

All Tests

npm run test                    # Run all tests (unit + E2E)

Unit Tests

npm run test:unit               # Run in watch mode (development)
npm run test:unit -- --run     # Run once and exit
npm run test:unit:coverage     # Run with coverage report (text output)
npm run test:coverage          # Interactive coverage UI with browser

# Run specific test files
npm run test:unit -- --run src/lib/services/pocketbase.test.ts
npm run test:unit -- --run src/lib/stores/auth.test.ts

Coverage Reports

npm run test:coverage          # Opens interactive Vitest UI with coverage
                              # - Live coverage visualization
                              # - Click-through source files
                              # - Real-time test running
                              # - Auto-opens at http://localhost:51204/__vitest__/

E2E Tests

npm run test:e2e                # Run all E2E tests headless
npm run test:e2e -- --headed   # Run with visible browser
npm run test:e2e -- --debug    # Run in debug mode

# Run specific test files or patterns
npm run test:e2e -- e2e/auth.test.ts
npm run test:e2e -- --grep "authentication"
npm run test:e2e -- --grep "should show welcome page"

Test Files Structure

src/
โ”œโ”€โ”€ lib/
โ”‚   โ”œโ”€โ”€ services/
โ”‚   โ”‚   โ””โ”€โ”€ pocketbase.test.ts      # PocketBase service tests
โ”‚   โ”œโ”€โ”€ stores/
โ”‚   โ”‚   โ””โ”€โ”€ auth.test.ts            # Authentication store tests
โ”‚   โ””โ”€โ”€ components/
โ”‚       โ””โ”€โ”€ auth/
โ”‚           โ””โ”€โ”€ LoginForm.test.ts   # Component tests (when needed)
โ”œโ”€โ”€ routes/
โ”‚   โ””โ”€โ”€ page.svelte.test.ts         # Route component tests
โ””โ”€โ”€ demo.spec.ts                    # Example unit test

e2e/
โ”œโ”€โ”€ auth.test.ts                    # Authentication flow tests
โ””โ”€โ”€ demo.test.ts                    # Example E2E test

# Test configuration
โ”œโ”€โ”€ vitest.config.ts                # Vitest configuration
โ”œโ”€โ”€ playwright.config.ts            # Playwright configuration
โ”œโ”€โ”€ vitest-setup-client.ts          # Client-side test setup
โ””โ”€โ”€ vitest-setup-server.ts          # Server-side test setup

Current Test Coverage

Unit Tests โœ… (74/74 passing)

  • PocketBase Service (src/lib/services/pocketbase.test.ts)

    • Authentication methods (login, register, OAuth)
    • Error handling and validation
    • Token management and refresh
    • File URL generation and utilities
  • Recipe Service (src/lib/services/recipe.test.ts)

    • CRUD operations with role-based filtering
    • Published status handling and visibility
    • Recipe creation, update, and deletion
    • URL and image extraction workflows
  • Authentication Store (src/lib/stores/auth.test.ts)

    • State management and reactivity
    • Login/logout workflows
    • Role-based derived stores
    • Error state handling

E2E Tests โœ… (50/50 passing)

  • Authentication Flows (e2e/auth.test.ts)

    • Welcome page for unauthenticated users
    • Login and registration form validation
    • OAuth button availability
    • Role-based UI differences (Admin vs Reader)
    • Navigation and redirects
    • Error message display
  • Recipe CRUD Operations (e2e/recipe-crud.test.ts)

    • Recipe creation, editing, and deletion
    • Form validation and error handling
    • Image upload functionality
    • Admin-only access controls
  • Recipe Full Flow (e2e/recipe-full-flow.test.ts)

    • Complete recipe creation workflows
    • Recipe viewing and navigation
    • Recipe editing with data persistence
  • Recipe Visibility & Publishing (e2e/recipe-visibility.test.ts)

    • Draft vs published recipe visibility
    • Role-based access to recipes
    • Publishing system functionality
    • Visual indicators for draft recipes
  • Error Handling (e2e/recipes.test.ts)

    • Invalid recipe ID handling
    • Network error scenarios
    • Proper error page display
    • Authentication-required routes

Development Workflow

For Test-Driven Development

# Start tests in watch mode while developing
npm run test:unit

# Start dev server for E2E testing
npm run dev:full  # Starts both PocketBase and SvelteKit

Before Committing

# Run all tests to ensure nothing is broken
npm run test

# Run linting and formatting
npm run lint
npm run format

Test Setup Requirements

For E2E Tests

The development server must be running:

npm run dev:full    # Recommended: starts both services
# OR separately:
npm run pocketbase  # Terminal 1
npm run dev         # Terminal 2

Playwright Browsers

Install required browsers (done automatically on first run):

npx playwright install

Writing New Tests

Unit Tests

Create .test.ts files next to your source files:

// src/lib/services/example.test.ts
import { describe, it, expect, vi } from 'vitest';
import { exampleFunction } from './example';

describe('Example Service', () => {
	it('should work correctly', () => {
		expect(exampleFunction()).toBe('expected result');
	});
});

E2E Tests

Add test files in the e2e/ directory:

// e2e/example.test.ts
import { test, expect } from '@playwright/test';

test.describe('Example Feature', () => {
	test('should work as expected', async ({ page }) => {
		await page.goto('/');
		await expect(page.getByText('Expected Text')).toBeVisible();
	});
});

Troubleshooting Tests

Common Issues

  1. E2E tests timeout or fail to start

    # Ensure dev server is running
    npm run dev:full
    
    # Check if PocketBase is accessible
    curl http://localhost:8090/api/health
  2. Unit tests can't find modules

    # Clear Vitest cache
    npm run test:unit -- --run --no-cache
  3. Playwright browser issues

    # Reinstall browsers
    npx playwright install --force
  4. Node version compatibility

    # Ensure Node 22.x is being used
    node --version
    asdf current nodejs

Debugging Tests

# Debug specific test with browser devtools
npm run test:e2e -- --debug --grep "specific test name"

# Run tests with verbose logging
npm run test:unit -- --run --reporter=verbose

# Generate test coverage report with interactive UI
npm run test:coverage

Continuous Integration

The test suite is designed to run in CI environments:

  • All tests run on every commit
  • E2E tests use headless browsers
  • Test results integrate with PR status checks
  • Coverage reports can be generated for monitoring

This comprehensive testing strategy ensures the authentication system is robust, reliable, and ready for production use.

๐Ÿš€ Deployment

Docker Deployment (Production Ready)

The app is configured for production deployment using Docker Compose with a custom PocketBase v0.29.0 image:

Prerequisites

  • Docker Engine 20.10+
  • Docker Compose 2.0+
  • Server with at least 2GB RAM and 10GB storage

Quick Start

# Clone the repository
git clone https://github.com/comdotlinux/ReceipeBox.git
cd ReceipeBox

# Configure environment
cd docker/
cp .env.production .env
# Edit .env with your settings

# Deploy
docker-compose up --build -d

# Check status
docker-compose ps
docker logs myrecipebox-pocketbase

Services

  • Frontend: SvelteKit app (port 3001) - http://localhost:3001
  • Backend: PocketBase v0.29.0 API (port 8090) - http://localhost:8090
  • Health Checks: Built-in container health monitoring
  • Volumes: Persistent data storage for database and uploads

Key Features

  • โœ… Custom PocketBase v0.29.0 - Official binary, latest features
  • โœ… Multi-stage builds - Optimized production images
  • โœ… Environment configuration - Flexible deployment settings
  • โœ… Health monitoring - Container dependency management
  • โœ… Persistent storage - Database and file uploads preserved

Alternative: Cloudflare Pages

For static deployment (frontend only):

  1. Connect your repository to Cloudflare Pages
  2. Set build command: npm run build
  3. Set output directory: dist
  4. Configure environment variables in Cloudflare
  5. Deploy separate PocketBase instance

๐Ÿ“– Documentation

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Write tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

๐Ÿ“„ License

This project is licensed under the MIT License.