尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Live: https://hearten-frontend.vercel.app
Meals that fit your health, your budget, and your table.
Hearten checks recipes against published guidelines for hypertension and type 2 diabetes, estimates cost per serving, and respects dietary requirements such as vegetarian, halal, kosher, gluten-free and common allergies.
Paste a recipe and Hearten matches each ingredient line to USDA food data, works out grams, and checks each serving against the plan you choose:
Educational only; not medical advice. Personal targets come from your care team. Nothing you enter is stored.
Status: version 1 (the recipe checker) is live. Version 2 is a weekly meal planner that uses optimization on top of the same engine.
Browser ── Vercel (static site: frontend/)
│ POST /check
▼
API Gateway (HTTP API, rate-limited) ── AWS Lambda (FastAPI, Python 3.13)
│ food catalogue loaded once per container
▼
Neon Postgres (12,213 USDA foods)
infra/ (Terraform) defines the Lambda, the HTTP API with throttling, logs, and IAM.main, GitHub Actions deploys through short-lived OIDC credentials scoped to updating this one function, then smoke-tests the live API. Vercel redeploys the site.You need Python 3.12+ and a Postgres database. The simplest option is a free Neon database: create a project, then copy its connection string.
cd backend
python -m venv .venv
.venv\Scripts\activate # macOS/Linux: source .venv/bin/activate
pip install -e ".[dev]"
# Point the app at your database: copy .env.example to .env in the repo root
# and paste your connection string into DATABASE_URL.
alembic upgrade head # create the tables
pytest # run the tests
uvicorn app.main:app --reload # http://127.0.0.1:8000/health
Prefer a local database? docker compose up -d db starts one, and the .env.example comment shows the matching URL.
frontend/ is a single static page (HTML, CSS and plain JavaScript, no build step): paste a recipe, set a plan, and read the results as an annotated recipe, with each line's USDA match and grams in the margin. Settings are saved in the browser only.
# with the API running on port 8000 (uvicorn app.main:app --reload)
cd frontend
python -m http.server 3000 # then open http://localhost:3000
backend/
app/ FastAPI app, settings, database models
migrations/ Alembic database migrations
app/ingredients/ recipe line parsing, food matching, gram conversion
app/rules/ guidelines, profile, dietary requirements, recipe check engine
app/catalog.py loads foods from Postgres and resolves recipe lines
scripts/ data download, import, tagging, matching evaluation
data/eval/ labeled recipe lines for the matching evaluation
tests/ pytest suite (runs in CI against a real Postgres)
frontend/ the website (static HTML, CSS, JavaScript)
infra/ Terraform: Lambda, HTTP API, IAM, GitHub deploy role
docker-compose.yml optional local Postgres
.github/workflows/ CI and deploys
Food, nutrient, price and added-sugar data come from USDA FoodData Central (FNDDS 2021-2023 and SR Legacy), USDA ERS Purchase to Plate, and USDA FPED. Inflation adjustment uses the BLS Consumer Price Index for food at home.
backend/data/bls_staples.csv). Cooking oil, salt and spices have no public average price, so they show as "price unavailable" unless the user enters their own.Each recipe line is parsed (amount, unit, food words), matched to a USDA food, and converted to grams using USDA portion weights. The matcher is lexical and explainable: word coverage weighted by rarity, the food's head word, penalties for dishes, brands and food parts, a preference for raw forms, and a tie-breaker from how often USDA's own survey recipes use each ingredient.
It's measured on 97 hand-labeled recipe lines (backend/data/eval/ingredient_lines.csv), split into a dev set used while tuning and a held-out test set scored only after tuning:
| Split | Lines | Correct food | Grams within 25% |
|---|---|---|---|
| dev | 60 | 100% | 98% |
| test (held out, first run) | 37 | 92% | 95% |
Adding FNDDS foods to the same search (so prepared foods like salsa or hummus match) scored 89% on its first test run; that run exposed a parsing bug in names with parentheses, which was fixed, bringing it back to 92%. Because that fix was prompted by the test set, the next evaluation should use freshly labeled lines.
python -m scripts.eval_matching # needs the downloaded USDA data
app/rules/ compares one recipe with a person's plan. Every limit cites its source in app/rules/guidelines.py:
Try it against your database from the command line, or through the API:
python -m scripts.check_recipe data/examples/chicken_stir_fry.txt --servings 4 \
--condition hypertension --budget 4.00 --diet halal
POST /check takes the pasted recipe, the number of servings and a profile, and returns each line's matched food and grams plus the full check. Nothing sent is stored. With the dev server running (uvicorn app.main:app --reload), interactive docs are at http://127.0.0.1:8000/docs.
{
"recipe": "1 lb chicken breast\n2 tbsp soy sauce\n1 cup long-grain white rice",
"servings": 4,
"profile": {"conditions": ["hypertension"], "diets": ["halal"], "budget_minor_per_meal": 400}
}
One-time setup (AWS CLI signed in, Terraform installed):
# 1. Store the database connection string, encrypted
aws ssm put-parameter --name /hearten/database_url --type SecureString --value "<connection string>"
# 2. Create the AWS resources
cd infra
terraform init
terraform apply # set create_github_oidc_provider = false in terraform.tfvars if your account has one
Then add two GitHub repository variables from the Terraform outputs: AWS_DEPLOY_ROLE_ARN (deploy_role_arn) and API_URL (api_url). From then on, every push to main that passes CI deploys the API. The website is a Vercel project with frontend/ as its root directory.