Reviewed-on: #14 Co-authored-by: Nicholas Ward <nicholaspward@outlook.com>
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 & Backups
SQLite is the canonical writable store. The database is located at
var/recipe-book.sqlite and is intentionally excluded from Git.
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.
Backup and Restore
To create a full, verifiable JSON backup of the active database:
npm run db:backup -- [path/to/backup.json]
To validate a backup bundle without modifying the database:
npm run db:validate -- path/to/backup.json
To restore a backup into SQLite (transactional replace mode):
npm run db:restore -- path/to/backup.json
Backups can also be downloaded and restored interactively through the web UI at /app/settings/.
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, 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.