- Resolve ingredient table overflow and 2-column layout on laptop screens (1280px-1440px) - Align recipe, ingredient, and directory pages with meez visual design specifications - Implement segmented icon navigation tabs across recipe and ingredient detail views - Standardize top utility bar and entity detail header alignment across all viewports - Fix mobile home page filter popup z-index and viewport overflow clipping - Clean up legacy prototype media queries and consolidate responsive CSS system
Formulation
Formulation is a culinary recipe-management application for building, scaling, costing, and analyzing professional recipes. It models ingredients and sub-recipes as reusable entities instead of embedding duplicated ingredient data in every recipe.
The Astro application can run as either the full editor or a server-enforced read-only viewer. Both modes provide recipes, ingredients, purchasing data, nutrition, live costs, scaling, conversions, and recipe books. Read-only mode removes persistent editing while retaining browser-side calculations.
Capabilities
- Structured recipes with components, sub-recipes, ordered preparation steps, yields, tags, and shelf life
- Recipe scaling using amounts, standard percentages, or baker's percentages
- Weight, volume, count, density, and ingredient-specific unit conversions
- Preparation yields and loss or gain factors
- Recursive nutrition and recipe costing
- USDA FoodData Central mappings with source provenance
- Ingredient aliases, purchasing packages, suppliers, and price history
- Nutrition labels and missing-data indicators
The culinary data model documents entity boundaries, measurement semantics, provenance, and portability conventions.
Requirements
- Node.js 22.12 or newer
- npm 9.6.5 or newer
- Python 3 for schema and content validation utilities
Install dependencies:
npm ci
python3 -m pip install --user -r requirements-dev.txt
Database
SQLite is the canonical writable store. The database is located at
var/recipe-book.sqlite and is intentionally excluded from Git. The single
baseline in migrations/001_initial.sql defines its complete schema.
All normal recipe, ingredient, nutrition-mapping, and purchasing changes must
be written to SQLite through the application or its validated database
functions. This rule also applies to automated and AI-assisted edits. Do not
edit culinary/*.yaml as a way to update a running application, and do not use
unrestricted SQL when saveRecipeStructure() or another domain save function
is available.
Create a new local database from the portable culinary dataset:
npm run db:reset
Warning: this command deletes and replaces the existing local database with
the contents of culinary/. Any newer SQLite-only edits will be lost. There is
intentionally no legacy upgrade chain. YAML under culinary/ is retained as
portable seed and interchange data; it is not a second writable source of
truth.
Generated projections and future YAML/JSON exports flow outward from SQLite. They are suitable for presentation, backup, interchange, and Git review, but must not be edited independently and treated as authoritative.
See Local application for more detail. For moving development to another machine, including the distinction between a seed rebuild and transferring current SQLite data, see Agent handoff.
Development
Run the editor:
npm run dev:app
Ingredient bulk entry uses the local Ollama service through
http://10.0.10.211:11434/api/chat and the purpose-built
qwen3:4b-instruct parsing prompt. Override these defaults with
FORMULATION_OLLAMA_URL and FORMULATION_INGREDIENT_PARSER_MODEL. The parser
endpoint is disabled whenever FORMULATION_READ_ONLY=true.
Open http://localhost:4322/app/.
To stop any process listening on the application port and start a fresh Astro development server:
npm run restart:app
Run the same application in read-only mode:
npm run dev:readonly
Open http://localhost:4399/app/. The database is opened read-only, modifying HTTP requests are rejected, and editing controls and routes are unavailable.
Validation and builds
Run type checks, unit tests, and the production build:
npm run check
npm test
npm run build
The standalone Node server is written to dist/app/. Start a production
read-only instance on port 4399 with npm run start:readonly.
Culinary data tools
Validate portable culinary entities, schemas, and cross-references:
scripts/validate-content
Search USDA FoodData Central and import a nutrition mapping:
USDA_FDC_API_KEY=... scripts/usda-fdc search "all-purpose flour"
USDA_FDC_API_KEY=... scripts/usda-fdc import flour_all_purpose 790018
Use --reviewed only after confirming that the selected record describes the
canonical ingredient. Never commit the USDA API key.
Purchasing candidates can be proposed from the sibling ledger receipt
archive and reviewed in the application:
scripts/receipt-products propose
scripts/receipt-products apply ~/Downloads/purchasing-decisions.json
The review interface is available at /tools/purchasing-review/.
Knowledge export
Generate the recipe corpus used by external knowledge systems:
scripts/corpus-export
The Gitea Actions workflow in .gitea/workflows/sync-knowledge.yml can publish
that corpus to an Open WebUI knowledge base. Configure these repository Actions
variables:
OPEN_WEBUI_URL
GOURMAND_KB_ID
Configure the API key as the KNOWLEDGE_SYNC_OPEN_WEBUI_API_KEY Actions secret.
Generated exports are not committed.