Files
component-system/README.md
2025-09-17 18:00:37 +02:00

381 lines
14 KiB
Markdown

# 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 <repository-url>
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