diff --git a/app/tiers.py b/app/tiers.py index 652544f..c3257ce 100644 --- a/app/tiers.py +++ b/app/tiers.py @@ -16,6 +16,8 @@ KIWI_BYOK_UNLOCKABLE: frozenset[str] = frozenset({ "expiry_llm_matching", "receipt_ocr", "style_classifier", + "meal_plan_llm", + "meal_plan_llm_timing", }) # Feature → minimum tier required @@ -33,7 +35,10 @@ KIWI_FEATURES: dict[str, str] = { "receipt_ocr": "paid", # BYOK-unlockable "recipe_suggestions": "paid", # BYOK-unlockable "expiry_llm_matching": "paid", # BYOK-unlockable - "meal_planning": "paid", + "meal_planning": "free", + "meal_plan_config": "paid", # configurable meal types (breakfast/lunch/snack) + "meal_plan_llm": "paid", # LLM-assisted full-week plan generation; BYOK-unlockable + "meal_plan_llm_timing": "paid", # LLM time fill-in for recipes missing corpus times; BYOK-unlockable "dietary_profiles": "paid", "style_picker": "paid", "recipe_collections": "paid", diff --git a/tests/test_meal_plan_tiers.py b/tests/test_meal_plan_tiers.py new file mode 100644 index 0000000..16da202 --- /dev/null +++ b/tests/test_meal_plan_tiers.py @@ -0,0 +1,27 @@ +# tests/test_meal_plan_tiers.py +from app.tiers import can_use + + +def test_meal_planning_is_free(): + """Basic meal planning (dinner-only, manual) is available to free tier.""" + assert can_use("meal_planning", "free") is True + + +def test_meal_plan_config_requires_paid(): + """Configurable meal types (breakfast/lunch/snack) require Paid.""" + assert can_use("meal_plan_config", "free") is False + assert can_use("meal_plan_config", "paid") is True + + +def test_meal_plan_llm_byok_unlockable(): + """LLM plan generation is Paid but BYOK-unlockable on Free.""" + assert can_use("meal_plan_llm", "free", has_byok=False) is False + assert can_use("meal_plan_llm", "free", has_byok=True) is True + assert can_use("meal_plan_llm", "paid") is True + + +def test_meal_plan_llm_timing_byok_unlockable(): + """LLM time estimation is Paid but BYOK-unlockable on Free.""" + assert can_use("meal_plan_llm_timing", "free", has_byok=False) is False + assert can_use("meal_plan_llm_timing", "free", has_byok=True) is True + assert can_use("meal_plan_llm_timing", "paid") is True