Skip to content

Add API endpoints for Home Assistant integration#271

Open
dubadub wants to merge 10 commits intomainfrom
ha-api-endpoints
Open

Add API endpoints for Home Assistant integration#271
dubadub wants to merge 10 commits intomainfrom
ha-api-endpoints

Conversation

@dubadub
Copy link
Member

@dubadub dubadub commented Mar 4, 2026

Summary

  • Add GET /api/stats endpoint returning recipe and menu counts
  • Add GET /api/menus endpoint listing all .menu files
  • Add GET /api/menus/*path endpoint returning parsed menu with sections, meals, date/time extraction via regex
  • Add GET /api/pantry/expiring?days=N endpoint returning items expiring within N days
  • Add GET /api/pantry/depleted endpoint returning low-stock pantry items
  • Include research, design, and implementation plan docs

These endpoints power the homeassistant-cookcli HACS custom component, which provides Calendar (meal plans from .menu files), Todo (shopping list), and Sensor entities for Home Assistant.

Menu calendar mapping

Menu sections with dates in parentheses (== Day 1 (2026-03-04) ==) are extracted via regex and mapped to HA calendar events. Meal type headers with times (Breakfast (08:30):) provide event start times. Sections without dates are ignored for calendar purposes but still included in shopping lists.

Test plan

  • cargo fmt passes
  • cargo clippy passes
  • cargo test passes
  • Manual test: cargo run -- server ./seed then curl http://localhost:9080/api/stats returns {"recipe_count":N,"menu_count":N}
  • Manual test: curl http://localhost:9080/api/menus returns list of menu files
  • Manual test: curl http://localhost:9080/api/menus/2%20Day%20Plan.menu returns parsed menu JSON
  • Manual test: curl http://localhost:9080/api/pantry/expiring?days=30 returns expiring items
  • Manual test: curl http://localhost:9080/api/pantry/depleted returns depleted items

dubadub added 8 commits March 4, 2026 17:33
Add a new stats API endpoint that returns the total number of recipes
and menus by recursively walking the recipe tree. This is the first
of several endpoints needed for Home Assistant integration.
Adds a new API endpoint that recursively walks the recipe tree and
returns all .menu files with their name and relative path, enabling
Home Assistant to discover available menu files for config flow.
Add a handler that parses .menu files and returns structured JSON with
sections grouped by meal type. Extracts dates from section names and
times from meal headers via regex. This endpoint powers the HA Calendar
entity by providing structured meal plan data.
Add GET /api/pantry/expiring?days=N and GET /api/pantry/depleted
endpoints for Home Assistant integration. The expiring endpoint
returns items expiring within N days (default 7) with days_remaining.
The depleted endpoint returns items flagged as low stock via is_low().
@cooklang cooklang deleted a comment from claude bot Mar 5, 2026
@cooklang cooklang deleted a comment from claude bot Mar 5, 2026
@cooklang cooklang deleted a comment from claude bot Mar 5, 2026
@cooklang cooklang deleted a comment from claude bot Mar 5, 2026
- Switch pantry handlers from std::fs to tokio::fs for async I/O
- Extract shared load_pantry() helper to deduplicate pantry parsing
- Validate days parameter rejects negative values (400 Bad Request)
- Add pantry_item_count, pantry_expiring_count, pantry_depleted_count to /api/stats
- Move json_error and check_path to shared common.rs module
- Reorder /menus before /menus/*path for clarity
- Add doc comment explaining why plain text items are excluded from menu API
@claude
Copy link

claude bot commented Mar 8, 2026

Code Review: Add API endpoints for Home Assistant integration

This is a solid, well-structured addition. The code is clean and the endpoint design is sensible. A few issues to address:

Security: No authentication on sensitive endpoints

The new /api/pantry/expiring and /api/pantry/depleted endpoints expose household pantry data to anyone who can reach the server. Since CookCLI is designed for local use, this is an accepted trade-off, but it is worth noting in the README or docs so users know not to expose the server publicly.

Bug: Ambiguous date format ordering in parse_date()

The formats array includes both "%d/%m/%Y" and "%m/%d/%Y". Since "%d/%m/%Y" is tried first, a date like "03/04/2026" will be parsed as April 3rd regardless of locale intent. Consider documenting the supported formats clearly, removing the ambiguous slash formats, or requiring ISO 8601 (%Y-%m-%d) only.

Inconsistency: Hardcoded 7-day threshold in /api/stats

The pantry_expiring_count in StatsResponse uses a hardcoded 7-day window, while /api/pantry/expiring accepts a configurable ?days=N parameter. The stats response does not document what threshold was used, which makes it hard to interpret. Either expose the threshold in the response or make it consistent with the endpoint default.

Code smell: AI prompt artifact in docs/plans/

The file docs/plans/2026-03-04-homeassistant-integration-plan.md begins with:
"> For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task."

This is an AI assistant prompt artifact that should be stripped before committing to the public repository.

Design: Large plan/research/design docs committed to source

Three large Markdown files are added under docs/plans/. These implementation notes are useful during development but are effectively dead weight in the release repository. Consider whether they belong in the wiki, an internal notes repo, or should be trimmed to just the design document (the research and plan files are mainly useful to the implementer, not future contributors).

Minor: Text items silently dropped from /api/menus response

The code explicitly discards LineItem::Text entries with a comment explaining that consumers should read the .menu file directly for raw text. This is a reasonable design decision, but it means plain-text connectors ("with", "served alongside", etc.) are lost. Consider noting this in the API documentation.

Minor: Missing sort order on /api/pantry/depleted

/api/pantry/expiring sorts by days_remaining (most urgent first), which is helpful. /api/pantry/depleted has no sort order -- consider sorting by section then name for consistent output.

Summary: Good implementation overall. The ambiguous date parsing, the 7-day hardcoded threshold inconsistency, and the AI artifact in the plan doc are the most important issues to fix before merge.

@cooklang cooklang deleted a comment from claude bot Mar 8, 2026
@cooklang cooklang deleted a comment from claude bot Mar 8, 2026
Merged main (v0.25.0) into ha-api-endpoints, preserving:
- Async I/O (tokio::fs) in pantry handlers
- Shared common.rs module for json_error/check_path
- load_pantry() helper to deduplicate parsing
- days validation in get_expiring
- Pantry counts in /api/stats

Incorporated from main:
- find_todays_menu() function
- pub visibility on collect_menus, extract_date, extract_meal_type, is_meal_header
- Today's menu banner feature
- Release v0.25.0 changes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant