# Components Inventory - Elixir/Phoenix Implementation A modern, idiomatic Elixir/Phoenix port of the original PHP-based component inventory management system. ## Features ### ✨ Improvements over the original PHP version: 1. **Modern Architecture** - Phoenix LiveView for real-time, reactive UI without JavaScript - Ecto for type-safe database operations - Proper separation of concerns with Phoenix contexts - Built-in validation and error handling 2. **Enhanced User Experience** - Real-time search with no page refreshes - Responsive design with Tailwind CSS - Loading states and better feedback - Improved mobile experience 3. **Better Data Management** - Full-text search with PostgreSQL - Hierarchical categories with parent-child relationships - Proper foreign key constraints - Database migrations for schema management 4. **Security & Reliability** - CSRF protection built-in - SQL injection prevention through Ecto - Session-based authentication - Input validation and sanitization ### 🔧 Core Functionality - **Component Management**: Add, edit, delete, and track electronic components - **Inventory Tracking**: Monitor component quantities with increment/decrement buttons - **Search & Filter**: Fast search across component names, descriptions, and keywords - **Category Organization**: Hierarchical category system for better organization - **Category Management**: Add, edit, delete categories through the web interface with hierarchical support - **Storage Location System**: Hierarchical storage locations (shelf → drawer → box) with automatic AprilTag generation - **AprilTag Integration**: Automatic AprilTag generation and display for all storage locations with download capability - **Datasheet Links**: Direct links to component datasheets - **Real-time Updates**: All changes are immediately reflected in the interface ## Setup 1. **Install dependencies:** ```bash mix deps.get ``` 2. **Set up the database:** ```bash docker run --name components-postgres -p 5432:5432 -e POSTGRES_PASSWORD=fCnPB8VQdPkhJAD29hq6sZEY -d postgres # password: config/dev.exs mix ecto.create mix ecto.migrate mix run priv/repo/seeds.exs ``` 3. **Start the server:** ```bash mix phx.server ``` 4. **Visit the application:** Open [http://localhost:4000](http://localhost:4000) ## Authentication The application uses a simple password-based authentication system: - Default password: `changeme` - Set custom password via environment variable: `AUTH_PASSWORD=your_password` ## Database Schema ### Categories - `id`: Primary key - `name`: Category name (required) - `description`: Optional description - `parent_id`: Foreign key for hierarchical categories - Supports unlimited nesting levels ### Components - `id`: Primary key - `name`: Component name (required) - `description`: Detailed description - `keywords`: Search keywords - `position`: Storage location/position - `count`: Current quantity (default: 0) - `datasheet_url`: Optional link to datasheet - `image_filename`: Optional image file name - `category_id`: Required foreign key to categories ## Architecture ### Contexts - **`ComponentsElixir.Inventory`**: Business logic for components and categories - **`ComponentsElixir.Auth`**: Simple authentication system ### Live Views - **`ComponentsElixirWeb.LoginLive`**: Authentication interface - **`ComponentsElixirWeb.ComponentsLive`**: Main component management interface - **`ComponentsElixirWeb.CategoriesLive`**: Category management interface - **`ComponentsElixirWeb.StorageLocationsLive`**: Hierarchical storage location management with AprilTags ### Key Features - **Real-time updates**: Changes are immediately reflected without page refresh - **Infinite scroll**: Load more components as needed - **Search optimization**: Uses PostgreSQL full-text search for long queries, ILIKE for short ones - **Responsive design**: Works on desktop and mobile devices ## API Comparison | Original PHP | New Elixir/Phoenix | Improvement | |-------------|-------------------|-------------| | `getItems.php` | `Inventory.list_components/1` | Type-safe, composable queries | | `getCategories.php` | `Inventory.list_categories/0` | Proper associations, hierarchical support | | `addItem.php` | `Inventory.create_component/1` | Built-in validation, changesets | | Manual editing | `Inventory.update_component/2` | **NEW**: Full edit functionality with validation | | `changeAmount.php` | `Inventory.update_component_count/2` | Atomic operations, constraints | | Manual category management | `CategoriesLive` + `Inventory.create_category/1` | **NEW**: Full category CRUD with web interface | | Manual location tracking | `StorageLocationsLive` + `Inventory` context | **NEW**: Hierarchical storage locations with automatic AprilTags | | `imageUpload.php` | Phoenix LiveView file uploads with `.live_file_input` | **IMPLEMENTED**: Full image upload with preview, validation, and automatic cleanup | | Session management | Phoenix sessions + LiveView | Built-in CSRF protection | ## 🚀 Future Enhancements ### Component Management - **Barcode Support** - Generate and scan traditional barcodes in addition to AprilTags - **Camera Integration** - JavaScript-based AprilTag scanning with camera access for mobile/desktop - **Multi-AprilTag Detection** - Spatial analysis and disambiguation for multiple tags in same image - **Bulk Operations** - Import/export components from CSV, batch updates - **Search and Filtering** - Advanced search by specifications, tags, location - **Component Templates** - Reusable templates for common component types - **Version History** - Track changes to component specifications over time ### Storage Organization - **Physical Layout Mapping** - Visual representation of shelves, drawers, and boxes - **Bulk AprilTag Printing** - Generate printable sheets of AprilTags for labeling ## ✅ Recently Implemented Features ### Storage Location System Foundation ✅ **COMPLETED** - **Database Schema** ✅ Complete - Hierarchical storage locations with parent-child relationships - **Storage Location CRUD** ✅ Complete - Full create, read, update, delete operations via web interface - **Hierarchical Organization** ✅ Complete - Unlimited nesting (shelf → drawer → box) - **Web Interface** ✅ Complete - Storage locations management page with navigation - **Component-Storage Integration** ✅ Complete - Components can now be assigned to storage locations via dropdown interface ### AprilTag System 🚧 **PARTIALLY IMPLEMENTED** - **Visual AprilTag Generation** ❌ Partially Implemented - Placeholder SVGs generated - **Flexible Assignment Options** ✅ Complete - Auto-assign, manual selection, or no AprilTag assignment for storage locations - **AprilTag Download** ✅ Complete - Individual AprilTag SVG files can be downloaded for printing - **AprilTag Scanning** ❌ Missing - No camera integration or scanning functionality (future enhancement) - **AprilTag Processing** ❌ Missing - Backend logic for processing scanned tags (future enhancement) ### Image Upload System ✅ **COMPLETED** - **Phoenix LiveView file uploads** with `.live_file_input` component - **Image preview** during upload with progress indication - **File validation** (JPG, PNG, GIF up to 5MB) - **Automatic cleanup** of old images when updated or deleted - **Responsive image display** in component listings with fallback placeholders - **Upload error handling** with user-friendly messages ### Visual Datasheet Indicators ✅ **COMPLETED** - **Datasheet emoji** (📄) displayed next to component names when datasheet URL is present - **Clickable datasheet links** with clear visual indication - **Improved component listing** with image thumbnails and datasheet indicators ### Technical Implementation Details #### Image Upload Architecture - **LiveView uploads** configured with `allow_upload/3` in mount - **File processing** with `consume_uploaded_entries/3` for secure file handling - **Unique filename generation** to prevent conflicts - **Static file serving** through Phoenix.Plug.Static with `/uploads` path - **Database integration** with `image_filename` field in components schema #### Upload Features - **File type validation**: Only JPG, PNG, GIF files accepted - **Size limits**: Maximum 5MB per file - **Single file uploads**: One image per component - **Progress indication**: Real-time upload progress display - **Cancel functionality**: Users can cancel uploads in progress - **Preview system**: Live image preview before form submission #### File Management - **Automatic cleanup**: Old images deleted when new ones uploaded - **Orphan prevention**: Images deleted when components are removed - **Error handling**: Graceful fallback for missing or corrupted files - **Static serving**: Images served directly through Phoenix static file handler ## Development ### Running Tests ```bash mix test ``` ### Code Quality ```bash mix format mix credo ``` ### Database Management ```bash # Reset database mix ecto.reset # Add new migration mix ecto.gen.migration add_feature # Check migration status mix ecto.migrations ``` ## Deployment ### 🐳 Docker Deployment (Recommended) #### Prerequisites - Docker and Docker Compose installed - Git for cloning the repository #### Quick Start 1. **Clone the repository:** ```bash git clone cd components_elixir ``` 2. **Copy docker-compose.yml.example to docker-compose.yml** Follow steps in [Customizing Docker Deployment](#customizing-docker-deployment). 3. **Build and run with Docker Compose:** ```bash docker compose up --build ``` **⚠️ Build Time Notice**: The initial build can take 5-15 minutes because: - Tailwind CSS downloads ~500MB from GitHub (can be very slow) - ESBuild downloads additional build tools - Elixir compiles all dependencies - Network conditions may significantly affect download speeds 4. **Access the application:** - Open [http://localhost:4000](http://localhost:4000) - Default password: `changeme` #### Docker Configuration Files The project includes these Docker files: - **`Dockerfile`** - Multi-stage build for production - **`docker-compose.yml`** - Local development/testing setup - **`.dockerignore`** - Excludes unnecessary files from build context #### Customizing Docker Deployment 1. **Environment Variables**: Edit `docker-compose.yml` to customize: ```yaml environment: DATABASE_URL: "ecto://postgres:postgres@db:5432/components_elixir_prod" SECRET_KEY_BASE: "your-secret-key-here" # Generate with: mix phx.gen.secret PHX_HOST: "localhost" # Change to your domain PHX_SERVER: "true" PORT: "4000" ``` 2. **Generate a secure secret key:** **With Elixir/Phoenix installed:** ```bash mix phx.gen.secret ``` **Without Elixir/Phoenix (Linux/Unix):** ```bash dd if=/dev/random bs=1 count=64 status=none | base64 -w0 | cut -c1-64 ``` > **Note**: The SECRET_KEY_BASE must be a cryptographically random string that's at least 64 characters long. Phoenix uses it to sign session cookies, CSRF tokens, and other security-sensitive data. 3. **Database Configuration**: The default setup includes: - PostgreSQL 15 container - Automatic database creation - Health checks to ensure proper startup order - Persistent data storage with Docker volumes #### Production Docker Deployment For production environments: 1. **Create a production docker-compose.yml:** ```yaml services: db: image: postgres:15 environment: POSTGRES_USER: components_user POSTGRES_PASSWORD: secure_db_password POSTGRES_DB: components_elixir_prod volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped app: build: . ports: - "80:4000" environment: DATABASE_URL: "ecto://components_user:secure_db_password@db:5432/components_elixir_prod" SECRET_KEY_BASE: "your-64-char-secret-key" PHX_HOST: "yourdomain.com" PHX_SERVER: "true" PORT: "4000" depends_on: db: condition: service_healthy restart: unless-stopped command: ["/bin/sh", "-c", "/app/bin/migrate && /app/bin/server"] volumes: postgres_data: ``` 2. **Deploy to production:** ```bash docker compose -f docker-compose.prod.yml up -d ``` #### Docker Troubleshooting **Build Issues:** - **Slow Tailwind download**: This is normal - GitHub releases can be slow - **Network timeouts**: Retry the build with `docker compose up --build` - **AprilTag compilation errors**: Ensure `apriltags.ps` file exists in project root **Runtime Issues:** - **Database connection errors**: Wait for PostgreSQL health check to pass - **Permission errors**: Check file ownership and Docker user permissions - **Port conflicts**: Change the port mapping in docker-compose.yml **Performance:** - **Slow startup**: First-time container startup includes database initialization - **Memory usage**: Elixir/Phoenix applications typically use 50-200MB RAM - **Storage**: PostgreSQL data persists in Docker volumes ### 🚀 Traditional Deployment For production deployment without Docker: 1. **Set environment variables:** ```bash export AUTH_PASSWORD=your_secure_password export SECRET_KEY_BASE=your_secret_key export DATABASE_URL=postgresql://user:pass@host/db ``` 2. **Build release:** ```bash MIX_ENV=prod mix release ``` 3. **Run migrations:** ```bash _build/prod/rel/components_elixir/bin/components_elixir eval "ComponentsElixir.Release.migrate" ``` ## Contributing This is a modernized, idiomatic Elixir/Phoenix implementation that maintains feature parity with the original PHP version while providing significant improvements in code quality, security, and user experience. The application follows Phoenix and Elixir best practices: - Contexts for business logic - LiveView for interactive UI - Ecto for database operations - Comprehensive error handling - Input validation and sanitization