Overview
BowlMix helps users decide what to make with the ingredients they already have. Users can manage their available ingredients and use them to generate bowl combinations across modular ingredient categories.
The project began as a way to make meals such as poke bowls less repetitive. It also became a full-stack product project covering product definition, UX/UI design, branding, frontend and backend development, API design, database modeling, documentation and deployment.
Problem
Meal inspiration does not always match the ingredients available at home. Bowl-based meals are well suited to a modular system because they combine ingredients from several categories, but recipe and inspiration tools often keep meal ideas separate from a user’s ingredient list.
BowlMix addresses this gap by generating combinations from the user’s available ingredients. Future versions could also use quantities and expiration dates to help prioritize food that should be used soon.
Solution
BowlMix combines an ingredient inventory with two ways to create bowls. Users can build a bowl with direct control or generate one from their available ingredients. Modular categories provide structure while leaving room for different combinations.
Key Features
- User authentication and profile management.
- An ingredient catalog with default and user-created ingredients.
- Ingredient availability management.
- Bowl generation based on available ingredients.
- Build and Generate modes for different levels of user control.
- Saved bowls with stable ingredient snapshots.
- Ingredient search and filtering.
- API documentation through OpenAPI and Swagger UI.
Technical Approach
BowlMix uses a separate frontend and backend. The React frontend handles the user experience, while the Flask backend provides a REST API for authentication, ingredient management, bowl generation and saved bowls. PostgreSQL stores users, ingredients, availability data and saved bowls.
Business rules live in dedicated service modules instead of route handlers. Flask Blueprints organize the API by domain, including authentication, ingredients, categories, bowls, saved bowls and demo functionality. Database changes use migrations, and OpenAPI with Swagger UI documents the public API contract.
The production setup uses Vercel for the frontend, Render for the Flask API and Supabase for PostgreSQL.
Engineering Decisions
Separating business logic from API routes
Service modules handle ingredient management, bowl generation, availability and saved bowls. Route handlers receive requests, validate inputs and return responses, which keeps HTTP concerns separate from application rules.
Snapshotting saved bowls
Saved bowls store a snapshot of their ingredient information. A saved combination therefore remains accurate if an ingredient is later renamed, edited or removed.
Soft deletion for ingredients
User-created ingredients can be referenced by other records. Soft deletion preserves those relationships while removing deleted ingredients from the active application.
Domain-based API organization
Domain-specific Blueprints keep related endpoints together and make individual areas of the backend easier to understand and maintain as the project grows.
API documentation during development
Defining the API contract with OpenAPI clarified endpoint behavior and made the backend easier to test and inspect independently from the frontend. Swagger UI makes the contract available to developers.
Deploying separate services
Running the frontend, backend and PostgreSQL database as separate services introduced production concerns including environment configuration, migrations, database connection strategies, CORS and deployment-specific behavior.
Challenges
The main challenge was defining how several connected concepts should work together, like ingredients, availability, categories, generation modes, saved bowls and user-created data.
Before implementation, I documented the product, data model, expected behavior and development phases. The goal was to create enough detail to guide architecture and implementation without specifying decisions that would be easier to make during development.
What I Learned
BowlMix strengthened my understanding of backend architecture, REST API design, relational data modeling, migrations, authentication, service-layer patterns, API documentation and production deployment.
The project also showed me how early product and architecture decisions affect implementation. Writing the specification and development phases before building most features made later decisions easier to evaluate.
I used AI-assisted development for research, implementation and review while retaining responsibility for the architecture and technical decisions. BowlMix also helped me combine product thinking, visual design, documentation and software engineering in one project.
Future Improvements
BowlMix is still in development. Planned improvements include:
- Expand automated testing across the frontend and backend.
- Add rate limiting for public and generation-related API endpoints.
- Add OAuth authentication.
- Containerize parts of the development environment with Docker.
- Improve the ingredient availability model.
- Add quantity and expiration-date tracking to prioritize ingredients that should be used soon.
- Refine the production deployment and developer experience.
- Evaluate a Turborepo structure if additional BowlMix applications or supporting tools are introduced.