# GitHub Copilot Instructions This is an electronic component inventory management system built with Phoenix LiveView. Follow these project-specific patterns for effective contributions. ## Project Architecture **Core Structure**: Phoenix 1.8 with LiveView-first architecture for real-time inventory management - `lib/components_elixir/` - Business logic contexts (Inventory, AprilTag, Auth) - `lib/components_elixir_web/live/` - LiveView modules for real-time UI - Key contexts: `Inventory` (components/categories/locations), `DatasheetDownloader`, `AprilTag` **Hierarchical Data Pattern**: Both categories and storage locations use unlimited nesting ```elixir # Use Hierarchical module for tree operations alias ComponentsElixir.Inventory.Hierarchical Hierarchical.build_tree(categories) # Converts flat list to nested structure ``` **Authentication**: Simple session-based auth using `ComponentsElixir.Auth` - All LiveViews must check `Auth.authenticated?(session)` in mount/3 - Default password: "changeme" (configurable via `AUTH_PASSWORD` env var) ## Key Development Workflows **Development Setup**: ```bash mix deps.get mix ecto.setup # Creates DB, runs migrations, seeds data mix phx.server # Starts dev server with hot reload ``` **Code Quality (Critical)**: Always run before committing ```bash mix precommit # Compiles with warnings-as-errors, formats, runs tests ``` **Database Operations**: ```bash mix ecto.reset # Drop/recreate/migrate/seed database mix ecto.gen.migration # Generate new migration ``` ## LiveView Patterns **Stream-Based Components**: Use LiveView streams for component lists to prevent memory issues: ```elixir # In LiveView stream(socket, :components, components) # In template
``` **File Upload Handling**: Uses Phoenix.LiveView.Upload with custom validators - Datasheets: PDF only, 10MB max, stored in `uploads/datasheets/` - Images: JPEG/PNG only, 5MB max, stored in `uploads/images/` ## Database Conventions **Hierarchical Relationships**: Self-referential `parent_id` foreign keys ```elixir # Schema pattern for categories/locations field :parent_id, :id belongs_to :parent, __MODULE__ has_many :children, __MODULE__, foreign_key: :parent_id ``` **Component Search**: Full-text search across name, description, keywords ```elixir # Use ilike for case-insensitive search from c in Component, where: ilike(c.name, ^"%#{search}%") ``` ## Asset Management **DaisyUI Components**: Prefer DaisyUI classes for consistent styling: - `btn btn-primary` for buttons - `card card-compact` for component cards - `badge` for category/location tags ## External Dependencies **AprilTag Generation**: SVG-based tags for physical location labeling ```elixir ComponentsElixir.AprilTag.generate_svg(tag_id) # Returns SVG string ``` ## Testing Guidelines **Factory Pattern**: Use explicit test data setup, not factories - Seed realistic test data in `test/support/` modules - Test both hierarchical and flat data structures ## Production Deployment **Docker-First**: Primary deployment method via `docker-compose.yml` - Environment: `SECRET_KEY_BASE`, `AUTH_PASSWORD`, `PHX_HOST` - File uploads mounted as volumes: `./uploads:/app/uploads` **Release Commands**: Database migrations via release tasks ```bash # In production container ./bin/components_elixir eval "ComponentsElixir.Release.migrate" ``` ## CI/CD with Gitea Actions **Gitea Actions Limitations** (important differences from GitHub Actions): - No `concurrency`, `run-name`, `permissions`, `timeout-minutes`, `continue-on-error` support - Limited expression support (only `always()` function) - No package repository authorization - use Personal Access Token for OCI publishing - Problem matchers and error annotations are ignored - Simple `runs-on` syntax only (`runs-on: ubuntu-latest`, not complex selectors) **CI Pipeline Will Include**: - Code quality checks (`mix precommit`) - Test execution across Elixir/OTP versions - Docker image building and publishing (requires PAT for package registry) - Database migration testing Ensure all code passes `mix precommit` before pushing, as this will be enforced in CI.