System Architecture
System Architecture
Section titled “System Architecture”React + Elixir/Phoenix Backend with Event Sourcing
Section titled “React + Elixir/Phoenix Backend with Event Sourcing”This document outlines a comprehensive architecture for a bar inventory and event management system using React with barcode scanning on the frontend and Elixir/Phoenix with Event Sourcing for the backend.
System Architecture Overview
Section titled “System Architecture Overview”Frontend (React with Scandit)
Section titled “Frontend (React with Scandit)”-
Main Application
- User authentication module
- Dashboard for quick inventory status and upcoming events
- Navigation to scanning, inventory, event planning, and recipe screens
-
Barcode Integration
- A component for barcode scanning
- Custom UI overlay for bar-specific actions:
- “Add to inventory” flow
- “Set bottle level” flow
- “Restock” flow
- “Add to bar setup” flow
-
Key Screens
- Dashboard (overview of events, inventory status, and shortcuts)
- Event planning screen (create/edit events, themes, guest lists)
- Menu design screen (create/edit menus for events)
- Inventory screen (current stock levels)
- Scan screen (for adding/using products)
- Recipe management screen (browse, create, edit recipes)
- Batch preparation screen (scale recipes for events)
- Bar setup screen (manage tools, equipment, and glassware)
- Reports screen (usage trends, popular drinks, event analytics)
Backend (Elixir/Phoenix with Event Sourcing)
Section titled “Backend (Elixir/Phoenix with Event Sourcing)”-
Core Domains
- Event Planning Domain: Managing events, themes, guests, and attendance
- Menu Management Domain: Creating and organizing drink menus
- Recipe Management Domain: Defining and maintaining cocktail recipes
- Inventory Domain: Tracking products, ingredients, and generating shopping lists
- Bar Setup Domain: Managing tools, equipment, and glassware
-
Core Aggregates
Event- Root entity for gatherings with themes, guest lists, and menusMenu- Collections of drink items designed for eventsRecipe- Definitions for cocktails with ingredients and preparation detailsInventory- Management of all available ingredients and productsBarSetup- Physical arrangement and tools needed for eventsBatchedCocktail- Scaled recipes prepared in advance for events
-
Event Sourcing Components
- Commands: Represent user intentions (CreateEvent, AddToInventory, etc.)
- Events: Record state changes (EventCreated, InventoryItemAdded, etc.)
- Aggregates: Enforce business rules and emit events
- Projections: Build read models from event streams
- Process Managers: Coordinate workflows across aggregates
-
Phoenix Contexts
Eventscontext for event planning and guest managementMenuscontext for menu creation and drink suggestionsRecipescontext for recipe creation, management, and batchingInventorycontext for product and stock managementBarSetupcontext for managing tools, equipment, and glasswareAnalyticscontext for reports and insightsAccountscontext for user management
-
LiveView Components (for admin dashboard)
- Real-time inventory monitoring
- Low stock alerts
- Upcoming event calendar
- Event preparation progress tracking
- Usage analytics graphs
-
API Endpoints (for mobile app)
- GraphQL API to serve the React app
- Authentication endpoints (JWT)
- Product lookup by barcode
- Inventory management endpoints
- Recipe and menu endpoints
- Event planning endpoints
- Batch calculation endpoints
Data Flow
Section titled “Data Flow”-
Event Planning Process
- User creates an event with theme, date, and expected guests
- System tracks guest RSVPs and preferences
- Attendance estimates are generated for planning purposes
-
Menu Design Process
- User creates menus for events with selected recipes
- System suggests drinks based on guest preferences and inventory
- Menu balance is analyzed for flavor diversity
-
Recipe Management Process
- User browses, creates, and edits cocktail recipes
- System maintains ingredient lists and preparation instructions
- Recipes can be tagged for easy organization
-
Batch Preparation Process
- User selects recipes to batch for an event
- System calculates scaled ingredients and adjustments
- Batch tracking monitors freshness and remaining servings
-
Scanning Process
- User scans bottle with Scandit
- App looks up product by barcode in local cache first
- If not found, queries Phoenix backend
- Shows product details and action options (add/use/restock)
-
Inventory Management Process
- When products are scanned and used, transactions are recorded
- Backend updates inventory levels in real-time
- System generates shopping lists based on planned menus and current inventory
- LiveView components reflect changes immediately for managers
-
Bar Setup Process
- User defines bar layout and required tools for events
- System verifies tool availability and suggests alternatives
- Setup instructions guide event preparation
Event Sourcing Implementation
Section titled “Event Sourcing Implementation”The system uses event sourcing to maintain a complete history of all domain events. This approach:
-
Records all changes as events:
- Every state change is captured as an immutable event
- Events are stored in chronological order in an event store
-
Rebuilds state from events:
- Aggregates load their state by replaying events
- Current state is a function of all past events
-
Provides complete audit trail:
- All actions and changes are preserved
- System state can be reconstructed for any point in time
-
Enables advanced analytics:
- Historical data is available for trend analysis
- Event patterns can reveal insights about usage and behavior
-
Supports eventual consistency:
- Read models are updated asynchronously
- Projections transform events into queryable views
Technology Stack
Section titled “Technology Stack”- Frontend: React with Vite, TypeScript, Tailwind CSS, shadcn/ui
- Backend: Elixir/Phoenix with Commanded for event sourcing
- Database: PostgreSQL for both event store and read models
- API: GraphQL with Absinthe
- Testing: Vitest for frontend, ExUnit for backend
- Deployment: Docker containers with CI/CD pipeline
Database Schema Design
Section titled “Database Schema Design”Core Entities
Section titled “Core Entities”Event Schema
Section titled “Event Schema”id: uuidname: stringdate: datetimedescription: textexpected_guest_count: integerstatus: enum (planned, in_progress, completed, cancelled)theme_id: uuid (foreign key)created_at: timestampupdated_at: timestampTheme Schema
Section titled “Theme Schema”id: uuidname: stringcolor_scheme: stringstyle: stringdescription: textsuggested_ingredients: jsonbcreated_at: timestampupdated_at: timestampGuest Schema
Section titled “Guest Schema”id: uuidevent_id: uuid (foreign key)name: stringemail: stringpreferred_spirits: array[string]disliked_ingredients: array[string]favorite_cocktails: array[string]allergies: array[string]rsvp_status: enum (invited, confirmed, declined, maybe, no_response)created_at: timestampupdated_at: timestampMenu Schema
Section titled “Menu Schema”id: uuidname: stringdescription: textevent_id: uuid (foreign key)is_final: booleancreated_at: timestampupdated_at: timestampDrinkItem Schema
Section titled “DrinkItem Schema”id: uuidmenu_id: uuid (foreign key)recipe_id: uuid (foreign key)name: stringdescription: textcategory: enum (signature, classic, mocktail, etc.)is_featured: booleanimage_url: stringcreated_at: timestampupdated_at: timestampRecipe Schema
Section titled “Recipe Schema”id: uuidname: stringdescription: textauthor: stringcreation_date: datetimeinstructions: textprep_time: intervalglass_type: enum (coupe, rocks, highball, etc.)ice_type: enum (cube, sphere, crushed, etc.)garnish_instructions: textrating: floatimage_url: stringcreated_at: timestampupdated_at: timestampRecipeIngredient Schema
Section titled “RecipeIngredient Schema”id: uuidrecipe_id: uuid (foreign key)ingredient_id: uuid (foreign key)quantity: floatunit: enum (oz, ml, dash, etc.)is_optional: booleansubstitute_group: stringcreated_at: timestampupdated_at: timestampBatchRecipe Schema
Section titled “BatchRecipe Schema”id: uuidbase_recipe_id: uuid (foreign key)serving_count: integerbatch_instructions: textprep_time: intervaldilution_factor: floatstability_duration: intervalcreated_at: timestampupdated_at: timestampProduct Schema
Section titled “Product Schema”id: uuidbarcode: stringname: stringbrand: stringtype: enum (spirit, wine, beer, mixer, etc.)category: string (vodka, gin, rum, etc.)alcohol_content: floatvolume: floatvolume_unit: enum (oz, ml, liter, etc.)current_amount: floatcurrent_unit: enum (oz, ml, liter, etc.)percentage_full: floatis_low: booleanis_empty: booleancost_price: decimalselling_price: decimalsupplier_id: uuid (foreign key)storage_location: stringexpiration_date: dateimage_url: stringcreated_at: timestampupdated_at: timestampIngredient Schema
Section titled “Ingredient Schema”id: uuidname: stringtype: enum (spirit, mixer, modifier, sweetener, garnish, other)current_stock: floatunit: enum (oz, ml, count, etc.)storage_location: stringproduct_id: uuid (foreign key, optional)created_at: timestampupdated_at: timestampShoppingList Schema
Section titled “ShoppingList Schema”id: uuidevent_id: uuid (foreign key)generated_date: datetimestatus: enum (draft, final, in_progress, completed)guest_count: integercreated_at: timestampupdated_at: timestampShoppingItem Schema
Section titled “ShoppingItem Schema”id: uuidshopping_list_id: uuid (foreign key)ingredient_id: uuid (foreign key, optional)product_id: uuid (foreign key, optional)tool_id: uuid (foreign key, optional)equipment_id: uuid (foreign key, optional)quantity: floatunit: enum (oz, ml, count, etc.)is_optional: booleanis_purchased: booleanbarcode: stringcreated_at: timestampupdated_at: timestampBarSetup Schema
Section titled “BarSetup Schema”id: uuidevent_id: uuid (foreign key)layout: textsetup_instructions: textcreated_at: timestampupdated_at: timestampBarTool Schema
Section titled “BarTool Schema”id: uuidname: stringtype: enum (shaker, strainer, jigger, etc.)quantity: integeris_essential: booleancategory_id: uuid (foreign key)barcode: stringcreated_at: timestampupdated_at: timestampEquipment Schema
Section titled “Equipment Schema”id: uuidname: stringtype: enum (blender, ice_crusher, carbonator, etc.)quantity: integeris_essential: booleancategory_id: uuid (foreign key)barcode: stringcreated_at: timestampupdated_at: timestampGlassware Schema
Section titled “Glassware Schema”id: uuidtype: enum (coupe, rocks, highball, etc.)quantity: integeris_essential: booleanbarcode: stringcreated_at: timestampupdated_at: timestampBatchedCocktail Schema
Section titled “BatchedCocktail Schema”id: uuidrecipe_id: uuid (foreign key)event_id: uuid (foreign key)batch_recipe_id: uuid (foreign key)creation_time: datetimeexpiration_time: datetimestorage_instructions: textserving_instructions: textremaining_servings: integercreated_at: timestampupdated_at: timestampTag Schema
Section titled “Tag Schema”id: uuidname: stringtype: enum (occasion, season, flavor, technique, etc.)created_at: timestampupdated_at: timestampTaggable Schema (polymorphic)
Section titled “Taggable Schema (polymorphic)”id: uuidtag_id: uuid (foreign key)taggable_id: uuidtaggable_type: stringcreated_at: timestampupdated_at: timestampTransaction Schema
Section titled “Transaction Schema”id: uuidproduct_id: uuid (foreign key, optional)ingredient_id: uuid (foreign key, optional)quantity: floatunit: stringtransaction_type: string (addition, usage, waste, etc.)user_id: uuid (who performed the action)recipe_id: uuid (optional, if used in a recipe)event_id: uuid (optional, if related to an event)notes: texttimestamp: timestampTechnical Implementation Details
Section titled “Technical Implementation Details”React + Scandit
Section titled “React + Scandit”- Implement offline-first approach with local storage
- Cache product data for fast lookup even without network
- Implement batch syncing for when connectivity is restored
- Use Scandit’s MatrixScan for batch scanning during restocking
- Handle low-light scanning conditions typical in bar environments
- Customize the scanning UI for easy one-handed operation
- Develop intuitive event planning and menu creation interfaces
- Implement flavor profile visualization for balanced menu design
Elixir/Phoenix Backend with Event Sourcing
Section titled “Elixir/Phoenix Backend with Event Sourcing”- Use domain-driven design with clearly defined bounded contexts
- Implement event sourcing using Commanded framework
- Store events in EventStore with PostgreSQL
- Create projections for read models using Ecto
- Use Phoenix PubSub for real-time inventory and event updates
- Create GenServers for handling background jobs like notifications
- Set up periodic inventory checks to alert on low stock
- Use Phoenix LiveView for real-time admin dashboard
- Implement GraphQL API with Absinthe for flexible mobile queries
- Develop batch scaling algorithms for cocktail preparation
- Implement proper context boundaries for maintainable code
Integration Points
Section titled “Integration Points”- GraphQL API for flexible communication between frontend and backend
- WebSockets for real-time updates to inventory, events, and menus
- Secure authentication using JWT tokens
- API versioning for future compatibility
- Phoenix Channels for real-time communication
- Barcode scanning integration with product database
- External calendar integration for event planning
Deployment Architecture
Section titled “Deployment Architecture”- Web app distributed through standard web hosting
- Phoenix backend deployed on cloud service with PostgreSQL database
- Implement CQRS pattern for read/write optimization
- Consider containerization for easy deployment and scaling
- Set up CI/CD pipeline for both frontend and backend
- Implement automated backups and disaster recovery
- Configure monitoring and alerting for system health
Security Considerations
Section titled “Security Considerations”- Role-based access control (RBAC) for different staff levels
- Encrypt sensitive data in transit and at rest
- Implement proper authentication and authorization
- Regular security audits and updates
- Consider compliance with local regulations regarding alcohol inventory
- Secure guest data with appropriate privacy controls
- Implement API rate limiting to prevent abuse
Future Expansion
Section titled “Future Expansion”- Integration with POS systems
- Automatic reordering based on inventory levels
- Customer-facing drink menu app that shows available drinks
- AI-powered drink recommendations based on inventory and guest preferences
- Sales analytics and predictive modeling
- Voice commands for hands-free operation during busy events
- Augmented reality overlay for bar setup guidance
- Integration with smart devices (scales, automatic pourers)
Implementation Phases
Section titled “Implementation Phases”-
Phase 1: Core Functionality
- Basic inventory management
- Barcode scanning with Scandit
- Simple recipe database
- Event and menu creation
-
Phase 2: Enhanced Features
- Real-time inventory updates
- Recipe suggestions and menu balancing
- Basic reporting
- Shopping list generation
- Batch recipe calculation
-
Phase 3: Advanced Features
- Advanced analytics
- Integration with suppliers
- Guest preference tracking
- AI-driven inventory optimization
- Bar setup optimization
- Mobile ordering for guests