diff --git a/app/tiers.py b/app/tiers.py new file mode 100644 index 0000000..c55b5ec --- /dev/null +++ b/app/tiers.py @@ -0,0 +1,34 @@ +"""Snipe feature gates. Delegates to circuitforge_core.tiers.""" +from __future__ import annotations +from circuitforge_core.tiers import can_use as _core_can_use, TIERS # noqa: F401 + +# Feature key → minimum tier required. +FEATURES: dict[str, str] = { + # Free tier + "metadata_trust_scoring": "free", + "hash_dedup": "free", + # Paid tier + "photo_analysis": "paid", + "serial_number_check": "paid", + "ai_image_detection": "paid", + "reverse_image_search": "paid", + "saved_searches": "paid", + "background_monitoring": "paid", +} + +# Photo analysis features unlock if user has local vision model (moondream2 (MD2) or similar). +LOCAL_VISION_UNLOCKABLE: frozenset[str] = frozenset({ + "photo_analysis", + "serial_number_check", +}) + + +def can_use( + feature: str, + tier: str = "free", + has_byok: bool = False, + has_local_vision: bool = False, +) -> bool: + if has_local_vision and feature in LOCAL_VISION_UNLOCKABLE: + return True + return _core_can_use(feature, tier, has_byok=has_byok, _features=FEATURES) diff --git a/tests/test_tiers.py b/tests/test_tiers.py new file mode 100644 index 0000000..bf8d3cf --- /dev/null +++ b/tests/test_tiers.py @@ -0,0 +1,23 @@ +from app.tiers import can_use, FEATURES, LOCAL_VISION_UNLOCKABLE + + +def test_metadata_scoring_is_free(): + assert can_use("metadata_trust_scoring", tier="free") is True + + +def test_photo_analysis_is_paid(): + assert can_use("photo_analysis", tier="free") is False + assert can_use("photo_analysis", tier="paid") is True + + +def test_local_vision_unlocks_photo_analysis(): + assert can_use("photo_analysis", tier="free", has_local_vision=True) is True + + +def test_byok_does_not_unlock_photo_analysis(): + assert can_use("photo_analysis", tier="free", has_byok=True) is False + + +def test_saved_searches_require_paid(): + assert can_use("saved_searches", tier="free") is False + assert can_use("saved_searches", tier="paid") is True