2025-05-27 17:35:12 +02:00
2025-05-27 15:01:07 +02:00
2025-05-27 17:35:12 +02:00
2025-05-27 14:43:00 +02:00
2025-05-26 21:55:49 +02:00
2025-05-26 21:55:49 +02:00
2025-05-26 21:55:49 +02:00
2025-05-26 21:55:49 +02:00
2025-05-27 14:43:00 +02:00
2025-05-26 20:20:21 +02:00
2025-05-26 20:20:21 +02:00
2025-05-26 21:59:31 +02:00

Product Tracker

A web application for tracking product prices and shopping events. Built with FastAPI (Python) backend and React (TypeScript) frontend.

Table of Contents

Features

  • Product Management: Add, edit, and track product items with prices, categories, and organic status
  • Shop Management: Manage different shops with locations
  • Shopping Events: Record purchases with multiple products and amounts
  • Price Tracking: Monitor price changes over time
  • Modern UI: Clean, responsive interface built with React and Tailwind CSS

Quick Start with Docker

The fastest way to get the application running is with Docker Compose:

Prerequisites

  • Docker Engine 20.10+
  • Docker Compose 2.0+

Deploy in 3 Steps

  1. Clone and setup:

    git clone <your-repo-url>
    cd groceries
    cp docker.env.example .env
    # Edit .env with your secure passwords
    
  2. Start all services:

    docker-compose up -d
    
  3. Initialize database:

    docker-compose exec backend alembic upgrade head
    

Access Your Application

For detailed Docker deployment instructions, see DOCKER_DEPLOYMENT.md.

Architecture

Technology Stack

Backend (Python):

  • FastAPI - Modern, fast web framework
  • SQLAlchemy - SQL toolkit and ORM
  • PostgreSQL - Relational database
  • Pydantic - Data validation and settings management
  • Alembic - Database migrations

Frontend (React):

  • React 18 with TypeScript
  • React Router - Client-side routing
  • Tailwind CSS - Utility-first CSS framework
  • Axios - HTTP client for API calls

Deployment:

  • Docker & Docker Compose
  • Nginx - Web server and reverse proxy
  • PostgreSQL - Production database

Component Communication

┌─────────────────┐    HTTP/REST API    ┌─────────────────┐    SQL Queries    ┌─────────────────┐
│   React         │ ←─────────────────→ │   FastAPI       │ ←───────────────→ │   PostgreSQL    │
│   Frontend      │     JSON requests   │   Backend       │   SQLAlchemy ORM  │   Database      │
│   (Port 80)     │     JSON responses  │   (Port 8000)   │                   │   (Port 5432)   │
└─────────────────┘                     └─────────────────┘                   └─────────────────┘

Data Model

Core Entities

Brands (brands table)

  • id: Integer, Primary key, Auto-increment
  • name: String, Brand name (indexed, required)
  • created_at: DateTime, Creation timestamp (auto-generated)
  • updated_at: DateTime, Last update timestamp (auto-updated)

Grocery Categories (grocery_categories table)

  • id: Integer, Primary key, Auto-increment
  • name: String, Category name (indexed, required)
  • created_at: DateTime, Creation timestamp (auto-generated)
  • updated_at: DateTime, Last update timestamp (auto-updated)

Groceries (groceries table)

  • id: Integer, Primary key, Auto-increment
  • name: String, Grocery item name (indexed, required)
  • category_id: Integer, Foreign key to grocery_categories (required)
  • created_at: DateTime, Creation timestamp (auto-generated)
  • updated_at: DateTime, Last update timestamp (auto-updated)

Products (products table)

  • id: Integer, Primary key, Auto-increment
  • name: String, Product name (indexed, required)
  • grocery_id: Integer, Foreign key to groceries (required)
  • brand_id: Integer, Foreign key to brands (optional)
  • organic: Boolean, Organic flag (default: false)
  • weight: Float, Weight/volume (optional)
  • weight_unit: String, Unit of measurement (default: "piece")
    • Supported units: "g", "kg", "ml", "l", "piece"
  • created_at: DateTime, Creation timestamp (auto-generated)
  • updated_at: DateTime, Last update timestamp (auto-updated)

Shops (shops table)

  • id: Integer, Primary key, Auto-increment
  • name: String, Shop name (indexed, required)
  • city: String, Location city (required)
  • address: String, Full address (optional)
  • created_at: DateTime, Creation timestamp (auto-generated)
  • updated_at: DateTime, Last update timestamp (auto-updated)

Shopping Events (shopping_events table)

  • id: Integer, Primary key, Auto-increment
  • shop_id: Integer, Foreign key to shops (required)
  • date: DateTime, Purchase date (required, default: current time)
  • total_amount: Float, Total cost of shopping event (optional, auto-calculated)
  • notes: String, Optional notes about the purchase
  • created_at: DateTime, Creation timestamp (auto-generated)
  • updated_at: DateTime, Last update timestamp (auto-updated)

Association Table

Shopping Event Products (shopping_event_products table)

Many-to-many relationship between shopping events and products with additional data:

  • id: Integer, Primary key, Auto-increment
  • shopping_event_id: Integer, Foreign key to shopping_events (required)
  • product_id: Integer, Foreign key to products (required)
  • amount: Float, Quantity purchased in this event (required, > 0)
  • price: Float, Price at time of purchase (required, ≥ 0)

Relationships

┌─────────────────┐    1:N    ┌─────────────────┐    1:N    ┌─────────────────┐    1:N    ┌─────────────────┐
│     Brands      │ ────────→ │    Products     │ ←──────── │    Groceries    │ ←──────── │ Grocery         │
│                 │           │                 │           │                 │           │ Categories      │
│ • id            │           │ • id            │           │ • id            │           │ • id            │
│ • name          │           │ • name          │           │ • name          │           │ • name          │
│ • created_at    │           │ • grocery_id    │           │ • category_id   │           │ • created_at    │
│ • updated_at    │           │ • brand_id      │           │ • created_at    │           │ • updated_at    │
└─────────────────┘           │ • organic       │           │ • updated_at    │           │ • updated_at    │
                              │ • weight        │           └─────────────────┘           └─────────────────┘
                              │ • weight_unit   │
                              │ • created_at    │
                              │ • updated_at    │
                              └─────────────────┘
                                       │
                                       │ N:M
                                       ▼
                              ┌─────────────────────────────┐
                              │  Shopping Event Products    │
                              │     (Association Table)     │
                              │                             │
                              │ • id                        │
                              │ • shopping_event_id         │
                              │ • product_id                │
                              │ • amount                    │
                              │ • price                     │
                              └─────────────────────────────┘
                                       │
                                       │ N:1
                                       ▼
┌─────────────────┐    1:N    ┌─────────────────┐
│     Shops       │ ────────→ │ Shopping Events │
│                 │           │                 │
│ • id            │           │ • id            │
│ • name          │           │ • shop_id       │
│ • city          │           │ • date          │
│ • address       │           │ • total_amount  │
│ • created_at    │           │ • notes         │
│ • updated_at    │           │ • created_at    │
└─────────────────┘           │ • updated_at    │
                              └─────────────────┘

Key Features

  • Hierarchical Product Organization: Products are organized by grocery type and category (e.g., "Apples" → "Fruits" → "Fresh Produce")
  • Brand Tracking: Optional brand association for products
  • Price History: Each product purchase stores the price at that time, enabling price tracking
  • Flexible Quantities: Support for decimal amounts (e.g., 1.5 kg of apples)
  • Auto-calculation: Total amount can be automatically calculated from individual items
  • Free Items: Supports items with price 0 (samples, promotions, etc.)
  • Audit Trail: All entities have creation timestamps for tracking
  • Data Integrity: Foreign key constraints ensure referential integrity

Development Setup

Prerequisites

  1. Python 3.8+ - For the backend
  2. Node.js 16+ - For the frontend
  3. PostgreSQL - Database

Backend Setup

  1. Navigate to backend directory:

    cd backend
    
  2. Create virtual environment:

    python3 -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    
  3. Install dependencies:

    pip install -r requirements.txt
    
  4. Setup database:

    # Create PostgreSQL database
    createdb product_tracker
    
    # Copy environment variables
    cp env.example .env
    
    # Edit .env with your database credentials
    nano .env
    
  5. Run database migrations:

    alembic upgrade head  # After setting up alembic
    
  6. Start the backend server:

    uvicorn main:app --reload
    

    The API will be available at http://localhost:8000 API docs at http://localhost:8000/docs

Frontend Setup

  1. Navigate to frontend directory:

    cd frontend
    
  2. Install dependencies:

    npm install
    
  3. Start the development server:

    npm start
    

    The app will be available at http://localhost:3000

API Endpoints

Brands

  • GET /brands/ - List all brands
  • POST /brands/ - Create new brand
  • GET /brands/{id} - Get specific brand
  • PUT /brands/{id} - Update brand
  • DELETE /brands/{id} - Delete brand

Grocery Categories

  • GET /grocery-categories/ - List all grocery categories
  • POST /grocery-categories/ - Create new grocery category
  • GET /grocery-categories/{id} - Get specific grocery category
  • PUT /grocery-categories/{id} - Update grocery category
  • DELETE /grocery-categories/{id} - Delete grocery category

Groceries

  • GET /groceries/ - List all groceries
  • POST /groceries/ - Create new grocery
  • GET /groceries/{id} - Get specific grocery
  • PUT /groceries/{id} - Update grocery
  • DELETE /groceries/{id} - Delete grocery

Products

  • GET /products/ - List all products
  • POST /products/ - Create new product
  • GET /products/{id} - Get specific product
  • PUT /products/{id} - Update product
  • DELETE /products/{id} - Delete product

Shops

  • GET /shops/ - List all shops
  • POST /shops/ - Create new shop
  • GET /shops/{id} - Get specific shop
  • PUT /shops/{id} - Update shop
  • DELETE /shops/{id} - Delete shop

Shopping Events

  • GET /shopping-events/ - List all shopping events
  • POST /shopping-events/ - Create new shopping event
  • GET /shopping-events/{id} - Get specific shopping event
  • PUT /shopping-events/{id} - Update shopping event
  • DELETE /shopping-events/{id} - Delete shopping event

Statistics

  • GET /stats/categories - Category spending statistics
  • GET /stats/shops - Shop visit statistics

Usage

  1. Add Shops: Start by adding shops where you buy products
  2. Add Products: Create product items with prices and categories
  3. Record Purchases: Use the "Add Purchase" form to record shopping events
  4. Track Prices: Monitor how prices change over time
  5. View Statistics: Analyze spending patterns by category and shop

Deployment

The application includes a complete Docker Compose setup for easy deployment. This is the recommended way to deploy the application in production.

Quick deployment:

# Clone repository
git clone <your-repo-url>
cd groceries

# Setup environment
cp docker.env.example .env
# Edit .env with your production values

# Deploy
docker-compose up -d

# Initialize database
docker-compose exec backend alembic upgrade head

Services included:

  • PostgreSQL database with persistent storage
  • FastAPI backend with health checks
  • React frontend served by Nginx
  • Automatic service restart and dependency management

For comprehensive deployment instructions, troubleshooting, and production considerations, see DOCKER_DEPLOYMENT.md.

Manual Deployment

For development or custom deployments, you can also run the services manually using the Development Setup instructions above.

Development

Running Tests

Backend:

cd backend
pytest

Frontend:

cd frontend
npm test

Database Migrations

cd backend
alembic revision --autogenerate -m "Description"
alembic upgrade head

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make changes
  4. Add tests
  5. Submit a pull request

License

MIT License

Description
No description provided
Readme 1.1 MiB
Languages
TypeScript 75.9%
Python 22.8%
Shell 0.4%
Dockerfile 0.4%
HTML 0.3%
Other 0.1%